0

特定の訪問に対するイベントを記録するために使用される単純なテーブルがあります。

Describe Histories;
    +------------------+
    | Field            |
    +------------------+
    | HistoryId        |
    | VisitId          |
    | Location         |
    | Event            |
    | EventTime        |
    +------------------+

個人はVisits(VisitId)に関連付けられています。訪問ごとに、個人は複数の履歴レコードを持つ場合があります。イベントは、入場、転送、または退院することができます。

各個人の各場所での期間を計算するクエリを作成しようとしています。訪問ごとに複数回ロケーションを訪問する場合があることに注意してください。個人は、入場または転送イベントでロケーションに入り、退院または転送で退出します。

個人がロケーション「A」に入ると、入場または転送レコードにロケーション「A」がリストされますが、転送(または退院)する場合は、別のロケーション、たとえば「B」がリストされます。

したがって、ロケーション'A'への転送とそれに続くロケーション'B'への(時間内の)転送の間の間隔を見つける必要があります。ロケーション内転送は評価されません。

解決策はおそらくINNERJOINに基づいていることを理解していますが、最新の転送「in」に対応する転送「out」レコードを選択する方法を理解するのに迷っています。

これはかなり複雑だと思います。説明が十分に明確になっていることを願っています。

どんなガイダンスでも大歓迎です。

4

2 に答える 2

1

転送または退院があなたがそのように書くことができるユニークなイベントであると仮定すると

SELECT
   b.EventTime - a.EventTime        
FROM
   Histories a
   INNER JOIN Histories b
   ON a.VisitID = b.VisitID
WHERE
   a.event = 'Admission'
   and
   b.event in ('Transfer', 'Discharge')

あなたが最後の転送または退院に興味があるなら、あなたは書くでしょう

SELECT
   b.EventTime - a.EventTime        
FROM
   Histories a
   INNER JOIN  Histories b
    ON a.VisitID = b.VisitID

   INNER JOIN 
   (SELECT
         VisitId, 
         MAX(HistoryID) HistoryID
    FROM Histories 
    WHERE 
       b.event in ('Transfer', 'Discharge')
    GROUP BY 
       VisitId) maxHistory
   ON b.HistoryID = maxHistoryId.HistoryId

WHERE
   a.event = 'Admission'

ただし、Andriy Mが言及しているように、訪問によって複数の訪問が発生する可能性がある場合は、ギャップと島(特に島)に問題があります。

その場合、あなたは以下が必要です

SELECT  
       a.VisitId,
       a.Event a_Event, 
       a.Event b_Event, 
       a.EventTime a_EventTime,
       b.EventTime b_EventTime,
       b_EventTime - a_EventTime

FROM   histories a 
       INNER JOIN histories B 
         ON a.visitID = b.visitID 
            AND a.EventTime < b.eventTime 
       INNER JOIN (SELECT a.VisitId, 
                          a.EventTime      a_EventTime, 
                          Min(b.EventTime) b_EventTime 
                   FROM   histories a 
                          INNER JOIN histories B 
                            ON a.visitID = b.visitID 
                               AND a.EventTime < b.eventTime 
                   GROUP  BY a_EventTime, 
                             a.VisitId) MinTime 
         ON a.VisitID = MinTime.VisitID 
            AND a.EventTime = a_EventTime 
            AND b.EventTime = b_EventTime 

デモ

次のサンプルデータを使用

CREATE TABLE Histories 
    (
     HistoryId int auto_increment primary key, 
     VisitId int,
     Location varchar(20),
     Event varchar(20), 
     EventTime datetime
    );

INSERT INTO Histories
(VisitId, Location, Event, EventTime)
VALUES
(1, 'A', 'Admission', '2012-01-01'),
(1, 'A', 'Discharge', '2012-01-03'),
(2, 'B', 'Admission', '2012-01-02'),
(2, 'C', 'Transfer', '2012-01-05'),
(2, 'C', 'Discharge', '2012-01-06'),
(3, 'D', 'Admission', '2012-01-06'),
(3, 'E', 'Transfer', '2012-01-07'),
(3, 'F', 'Transfer', '2012-01-08'),
(3, 'F', 'Discharge', '2012-01-10');

次の結果が得られます

VISITID    A_EVENT   B_EVENT    A_EVENTTIME                     B_EVENTTIME                     B_EVENTTIME - A_EVENTTIME
1          Admission Discharge  January, 01 2012 00:00:00-0800  January, 03 2012 00:00:00-0800  2000000
2          Admission Transfer   January, 02 2012 00:00:00-0800  January, 05 2012 00:00:00-0800  3000000
2          Transfer  Discharge  January, 05 2012 00:00:00-0800  January, 06 2012 00:00:00-0800  1000000
3          Admission Transfer   January, 06 2012 00:00:00-0800  January, 07 2012 00:00:00-0800  1000000
3          Transfer  Transfer   January, 07 2012 00:00:00-0800  January, 08 2012 00:00:00-0800  1000000
3          Transfer  Discharge  January, 08 2012 00:00:00-0800  January, 10 2012 00:00:00-0800  2000000

ノート:

  • これは、対応する排出/転送がまだない入場/転送を気にしないことを前提としています。
  • レコードが入力された後もeventTimeが変更されないことがわかっている場合は、偶数時間の代わりにhistoryIDを使用してイベントの順序を決定できます。
  • あなたはあなたが好きなフォーマットでイベント時間の違いを得る方法を知っています
于 2012-05-07T03:56:19.967 に答える
1

これはどのように機能しますか?

SELECT 
    h1.HistoryId, 
    h1.VisitId, 
    h1.Event AS InitialEvent, 
    h2.Event AS FinalEvent, 
    h1.Location AS StartLocation,
    h2.Location AS EndLocation,
    IF(h2.HistoryId, UNIX_TIMESTAMP(h2.EventTime) - UNIX_TIMESTAMP(h1.EventTime), NULL) AS transfer_duration_seconds
FROM Histories h1 
LEFT JOIN Histories h2 ON h1.VisitId = h2.VisitId AND h1.Location != h2.location AND h2. EventTime > h1. EventTime
GROUP BY h1.VisitId
于 2012-05-07T03:57:01.317 に答える