我有一个简单的表,用于记录针对特定访问的事件:
Describe Histories; +------------------+ | Field | +------------------+ | HistoryId | | VisitId | | Location | | Event | | EventTime | +------------------+
个人与访问次数(VisitId)相关联。对于每次访问,一个人可能有多个历史记录。活动可以是入场,转场或出场。
我试图编写一个查询来计算每个位置在每个位置的持续时间。请注意,他们每次访问可能会多次访问一个位置。个人通过录取或转移事件进入场所,然后通过放电或转移离开场所。
如果某人进入位置“ A”,其录取或转移记录将列出位置“ A”,但是如果他们转移出去,其转移(或释放)将列出另一个位置,例如“ B”。
因此,我必须找到转移到位置“ A”和随后(及时)转移到位置“ B”之间的间隔。不评估位置内转移。
我知道该解决方案可能基于INNER JOIN,但是我不知该如何选择与最近的转帐“ in”相对应的转帐“ out”记录。
我认为这是相当复杂的-希望我的解释足够清楚。
任何指导,不胜感激。
假设转移或释放是一个独特的事件,您可以这样写
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
笔记: