在SQL中连接顺序记录

时间:2011-01-29 04:19:06

标签: tsql

我有一个包含各种信息的消息数据库。其中一个是状态更改消息,所以我的表格如下所示。

    +-----------+--------------+---------+
    | 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与它结合起来,并且在线性时间内有我想要的数据。

1 个答案:

答案 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