2012-05-07 9 views
0

テーブルで特定のレコードや関連イベントの間隔を決定するためにJoinを使う私は、特定の訪問に対してイベントを記録するために使用される単純なテーブルを持っている:インナー

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

個人を訪問(VISITID)に関連しています。訪問ごとに、個人は複数の履歴レコードを持つことができます。イベントは、入場、移転または退院とすることができます。

私は各個人の各場所の期間を計算するクエリを作成しようとしています。訪問ごとに場所を複数回訪問する可能性があることに注意してください。個人は、入場または移転イベントで場所を入力し、退出または移転を行います。個々の場所「A」、彼らの入学を入力するか、別の場所の一覧が表示されます彼らは彼らの転送を行う転送(または放電)があれば、場所「A」を一覧表示されます、レコードを転送した場合

は、「B」を言います。

Iしたがって場所「A」に転送し、場所「B」に続く(時間的に)転送間隔を見つけなければなりません。イントラロケーション転送は評価されません。

解決策はおそらくINNER JOINに基づいていると私は理解していますが、最新の転送 "in"に対応する転送 "out"レコードの選択方法を理解することは紛失しています。

これは合理的に複雑だと思います。私は私の説明で十分明確であることを願っています。

ご迷惑をおかけして申し訳ございません。転送または放電を想定し

答えて

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' 

を書くと放電する可能性がユニークなイベントですアンドリー・Mあなたはを、次のあなたがしたいような場合にはギャップや島々の問題(特に島)

を持って言及しているように、複数の訪問につながります次のサンプルデータ

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'); 

使用

DEMO

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 
ます取得するには、次の結果

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を使用してイベントの順序を判断できます。
  • あなたは、あなたのためにこの仕事をしてどのよう
+0

ありがとうございます。最初の例は非常に参考になりましたが、2番目の例は私が探している構造にもっと役立ちました。私はまだ苦労している2つの分野があると思う。主なものは、私があなたの例の中で最も最近のものではなく、次の移転または退出で入場または移転を場所に関連付ける必要があることです。 1人の個人が1つの場所に対して複数の「イン/アウト」イベントを持つことができます。 – skyman

+0

@bugy:同じ「VisitId」の同じ場所への複数の転送がありますか? –

+0

はい。個人は「クリニック」を訪問することができます。クリニック訪問はVisitIdに関連付けられています。しかし、訪問の間に、彼らはある部屋から別の部屋に移動し、すでに入っていた部屋に戻ってくるかもしれません。彼らが部屋に入るたびに、履歴記録が作成されます(入場または転送)。彼らが出発するたびに、履歴レコードが作成されます(移送または退出)。問題は、特定の部屋の滞在期間を決定することです。これは、「イン」イベントとそれに続く「アウト」イベントとの間の時間差になる。 – skyman

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 
+0

ブライアンありがとう - これも意味をなさない。しかし、COnradの場合と同様に、InitialEventとSubsequentEventを関連付けるのに苦労しています。それぞれのVisitIdに対して複数のペアが存在する可能性があります。 – skyman

+0

私は少し混乱しています、私のクエリは、歴史から各イベントをつかむべきであり、EventTimeに従って次の連続イベントに参加する必要があります。それ以外の何かをしていますか? – Bryan

関連する問題