我有一张充满活动的桌子。我被要求创建一个聚合会话表;一个会话可能有几个事件。通过具有相同的到达时间来识别会话。例如(这是一种简化,我没有输入实际的时间戳):
EventID ArrivalTime StartTime EndTime StaffID 1 0945 0950 0955 John 2 0945 0955 1000 Barb
可能变成类似的东西:
ArrivalTime StartTime EndTime StaffID 0945 0950 1000 ???
使用MIN(StartTime)
和MAX(EndTime)
将其保留为一行。
正如上面的问题所示,我遇到的问题是获得一个工作人员身份证 - 这个工作人员并不重要,但我需要一个人。如果它只是一个字符串,正如我上面所示,它可以用MIN(StaffID)
来完成,但我正在做的事情就是我需要在Staff表中查找StaffID并拔出与我表中的短代码相关联的GUID。并且GUID不喜欢像MIN()
这样的函数。另外,更糟糕的是,事件表中的StaffID列是NULL
是可行的,所以我必须坚持左连接或类似。
有人提出了一个子查询,但显然我的大脑在星期五拒绝接受这个,并且看不到如何让它工作。
作为基线,这是我当前查询的内容:
SELECT NEWID() AS SessionID,
e.ArrivalTime,
MIN(e.StartTime),
MAX(e.EndTime),
s.StaffGUID
FROM Events e LEFT JOIN Staff s ON e.StaffID = s.StaffID
GROUP BY e.ArrivalTime, s.StaffGUID
问题是如果列表中有两个不同的工作人员,会话将显示两次。有什么想法吗?
答案 0 :(得分:2)
有相关的subselect选项(使用TOP的2000+):
SELECT NEWID() AS SessionID,
e.ArrivalTime,
MIN(e.StartTime),
MAX(e.EndTime),
(SELECT TOP 1 s.StaffGUID
FROM STAFF s
WHERE s.staffid = e.staffid) AS staffguid
FROM EVENTS e
GROUP BY e.arrivaltime, e.staffguid, staffguid
...或派生表/内联视图(使用ROW_NUMBER的2005+):
SELECT NEWID() AS SessionID,
e.ArrivalTime,
MIN(e.StartTime),
MAX(e.EndTime),
s.staffguid
FROM EVENTS e
LEFT JOIN (SELECT t.staffid,
t.staffguid,
ROW_NUMBER() OVER (PARTITION BY t.staffid) AS rank
FROM STAFF t) s ON s.staffid = e.staffid
AND s.rank = 1
GROUP BY e.arrivaltime, s.staffguid
我的偏好是派生表 - 相关的子查询往往不能正常运行。