我有一个包含各种信息的消息数据库。其中一个是状态更改消息,所以我的表格如下所示。
+-----------+--------------+---------+ | MessageId | RecievedUTC | State | +-----------+--------------+---------+ | 1 | 1/1/2010 5pm | Off | +-----------+--------------+---------+ | 2 | 1/2/2010 8am | Idle | +-----------+--------------+---------+ | 3 | 1/2/2010 9am | Working | +-----------+--------------+---------+
我想得到一份记录清单,说明我在每个州的状况,以及报告的时间,以及可能是时间花费的漂亮条形图。
+---------+---------------+--------------+ | State | StartUTC | StopUTC | +---------+---------------+--------------+ | Off | 1/1/2010 5pm | 1/2/2010 8am | +---------+---------------+--------------+ | Idle | 1/1/2010 8am | 1/2/2010 9am | +---------+---------------+--------------+
等。在我看来,它并不比表格与自身的连接更难,而是由RecievedUTC订购的1条记录所抵消。
我能想出的最佳TSQL是
的效果SELECT m1.State, m1.RecievedUTC as StartUTC, MIN(m2.RecievedUTC) as StopUTC
FROM MessageStates as m1
INNER JOIN MessageStates as m2 ON MessageStates ON m2.RecievedUTC > m1.RecievedUTC
GROUP BY m1.MessageId, m1.State, m1.RecievedUTC
或者作为获取StopUTC的子查询,但两者都只有30-40k的记录,只花了将近5分钟的时间来执行此连接。
如果我用C#写这个,我会跟踪前面的RecievedUTC和状态,所以当我看到下一条记录时,我可以将下一个RecievedUTC与它结合起来,并且在线性时间内有我想要的数据。
答案 0 :(得分:2)
试试这个:
WITH MsgStates AS
(
SELECT a.*, ROW_NUMBER() OVER(ORDER BY RecievedUTC ) RN
FROM MessageStates a
)
SELECT a.State, a.RecievedUTC StartUTC, b.RecievedUTC StartUTC
FROM MsgStates a, MsgStates b
WHERE a.rn = b.rn+1