2012-05-07 34 views
0

特定的記錄和相關事件之間的間隔我有一個用於記錄事件針對特定訪問一個簡單的表:使用內連接來確定表中

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

個人與訪問(VisitId)相關聯。對於每次訪問,個人可能有多個歷史記錄。活動可以是錄取,轉移或放電。

我想寫一個查詢來計算每個人在每個位置的持續時間。請注意,他們可能會每次訪問多次訪問一個地點。個人進入有錄取或轉移事件的地點,並隨着出院或轉移離開。

如果個人進入地點'A',他們的入場或轉移記錄將列出地點'A',但是如果他們轉出他們的轉出(或出院)將列出另一個地點,如'B'。

因此,我必須找到轉移到地點'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' 

一個獨特的事件然而,如果訪問能導致多次訪問,因爲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 

DEMO

使用下面的示例數據

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而不是eventime來確定事件的順序。
  • 你知道如何讓你喜歡的
+0

謝謝你。第一個例子非常有幫助,雖然第二個例子更接近我期待的結構。我認爲還有兩個領域我正在掙扎。主要的一點是,我需要將入場或轉入地點與下一次轉會或轉出相關聯,而不是您的示例中最近的一次。一個人可能有多個「進/出」事件的單個位置。 – 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