如何基于可变时间戳记录分区数据 - SQL

时间:2014-02-18 19:38:36

标签: sql sql-server group-by

我有一个像这样的SQL数据库:

Id    Text       DateTime
----------------------------
1     Event1     1/1/1900 12:00:00
2     Event2     1/1/1900 12:10:11
3     Event3     1/1/1900 12:11:10
4     Event2     1/1/1900 12:12:12
5     Event3     1/1/1900 12:13:19
6     Event1     1/1/1900 12:14:22
7     Event2     1/1/1900 12:15:15
8     Event2     1/1/1900 12:18:16
9     Event3     1/1/1900 12:23:00
10    Event3     1/1/1900 12:24:11

我想找到哪个事件首先发生,由Event1发生分区。即哪个事件2发生在任何其他事件2之前,但事件发生在事件1之后。

到目前为止,我有类似的内容:

SELECT t1.* from Database t1 join
(select ROW_NUMBER() OVER
(PARTITION BY Text ORDER BY DateTime ASC) AS Ranking,
Id from Database
where  DateTime>(select MAX(DateTime) from Database where Text = 'Event1')) t2
on t1.id=t2.id and t2.Ranking=1

这仅适用于最后的事件(因为我使用的是MAX)。是否有一些聪明的方法可以做到这一点我看不到?

编辑: 澄清,我想要标记所有事件(包括事件1或不事件,无关紧要),如果它们是事件1发生后发生的第一个事件。

在这种情况下,输出看起来像:

Id
---
2
3
7
9

Id
---
1
2
3
6
7
9

2 个答案:

答案 0 :(得分:0)

如果第一个Event2始终以Event1开头,您可以使用:

WITH cte AS (SELECT *,ROW_NUMBER() OVER (ORDER BY DateTime) RN
             FROM Table1)
SELECT b.*
FROM cte a
JOIN cte b
 ON a.text = 'event1' and b.text = 'event2'
 AND a.RN = b.RN - 1

演示:SQL Fiddle

答案 1 :(得分:0)

  

我正在对你的Row_Number()做一些修改。我正在设置它   新的partiton Id我的逻辑。请包涵。这里我要创建一个分区   对于每个Event1,2,3下一个Event1,2,3等使用Cursor,   因为没有其他可能采取分区。

 DECLARE @ROW INT=0,
        @TEXT VARCHAR(10),
        @DATETIME DATETIME,
        @TMPDATE DATETIME,
        @CUR CURSOR

        SET @CUR = CURSOR FOR SELECT #TABLE.Text [Text],#TABLE.[DateTime] FROM #TABLE
                   ORDER BY [DateTime]

        OPEN @CUR           
            FETCH NEXT FROM @CUR INTO @TEXT,@DATETIME
            WHILE @@FETCH_STATUS = 0   
            BEGIN   

                IF(@TEXT='Event1')
                BEGIN

                    SET @ROW=@ROW+1;

                END

                UPDATE #TABLE SET ID=@ROW WHERE [Text]=@TEXT AND [DateTime]=@DATETIME;  

                FETCH NEXT FROM @CUR INTO @TEXT,@DATETIME       
            END

        CLOSE @CUR
        DEALLOCATE @CUR
  

现在我要去分区,根据Id和Text来获取   最短日期时间

        SELECT DISTINCT ID,[TEXT]
        ,CASE WHEN [TEXT]= 'EVENT1' THEN [DateTime] ELSE MIND END [DATETIME]        
        FROM
        (
            SELECT ID,[Text],[DateTime]
            ,MIN([DATETIME]) OVER(PARTITION BY ID,[Text]) MIND
            FROM #TABLE 
        )TAB
        ORDER BY [DATETIME]