2010-03-22 60 views
1

我有一張數據表,表示人們隨着時間的推移而發生的一系列事件,有時候人們連續多次做同樣的事情。如何使用MS SQL 2008選擇僅顯示這些事件的消歧序列的結果?如何消除sql中的序列歧義?

Source data: 
Person Event Time 
1  2  1 
1  2  20 
1  2  33 
2  1  34 
1  4  43 
1  2  44 
2  3  45 
1  2  46 
1  3  50 
1  3  55 

Result: 
Person Event 
1  2 
2  1 
1  4 
1  2 
2  3 
1  3 
+2

定義消歧?第一?持續? – TomTom 2010-03-22 13:34:00

+0

我已經看了三次結果序列,我仍然無法弄清楚構建它的規則。你能解釋一大堆*嗎? – 2010-03-22 13:49:13

+0

我需要一個列表,其中同一個人的兩個同類事件沒有及時跟隨彼此。如果序列是2 2 2 4 4 2 2 3 3 3 4 4,那麼我需要2 4 2 3 4. – Martin 2010-03-22 13:58:04

回答

2

試試這個:

DECLARE @YourTable table (Person int, Event int, Time int) 
SET NOCOUNT ON 
INSERT INTO @YourTable VALUES (1, 2 , 1) 
INSERT INTO @YourTable VALUES (1, 2 , 20) 
INSERT INTO @YourTable VALUES (1, 2 , 33) 
INSERT INTO @YourTable VALUES (2, 1 , 34) 
INSERT INTO @YourTable VALUES (1, 4 , 43) 
INSERT INTO @YourTable VALUES (1, 2 , 44) 
INSERT INTO @YourTable VALUES (2, 3 , 45) 
INSERT INTO @YourTable VALUES (1, 2 , 46) 
INSERT INTO @YourTable VALUES (1, 3 , 50) 
INSERT INTO @YourTable VALUES (1, 3 , 55) 
SET NOCOUNT OFF 

;WITH Ranked AS 
(SELECT 
    Person,Event,Time 
    ,ROW_NUMBER() OVER(PARTITION by Person order by time,Person, Event) AS RowNumber 
    FROM @YourTable 
) 
SELECT 
    r1.Person,r1.Event 
    FROM Ranked    r1 
     LEFT OUTER JOIN Ranked r2 ON r1.RowNumber=r2.RowNumber-1 AND r1.Person=r2.Person 
    WHERE r1.Event!=ISNULL(r2.Event,-999) 

OUTPUT:

Person  Event 
----------- ----------- 
1   2 
1   4 
1   2 
1   3 
2   1 
2   3 

(6 row(s) affected) 

OP不說哪個版本的SQL Server,所以這裏的CTE免費版預SQL Server 2005,輸出如上:

SELECT 
    r1.Person,r1.Event 
    FROM (SELECT 
       Person,Event,Time 
       ,ROW_NUMBER() OVER(PARTITION by Person order by time,Person, Event) AS RowNumber 
       FROM @YourTable 
     ) r1 
     LEFT OUTER JOIN (SELECT 
          Person,Event,Time 
          ,ROW_NUMBER() OVER(PARTITION by Person order by time,Person, Event) AS RowNumber 
          FROM @YourTable 
         ) r2 ON r1.RowNumber=r2.RowNumber-1 AND r1.Person=r2.Person 
    WHERE r1.Event!=ISNULL(r2.Event,-999) 
+0

不漂亮,但有效! SQL Server 2008是否具有lag()分析功能? (我知道2005年沒有)如果是這樣,你可以做到這一點,而無需使用CTE /掃描表兩次。 – araqnid 2010-03-22 14:33:19

-1

選擇的人,事,最後(一次)從X 組的人,事件

+2

最後只有MS Access我認爲。需要使用其他一些聚合。 – 2010-03-22 13:38:06

0

我不知道如果我得到你的權利。也許你想

SELECT DISTINCT Person, Event FROM Table Where 1 ORDER BY Person; 

這會選擇你所有的行,但刪除重複。因此,這應該產生:

Result: 
Person Event 
1  2 
1  4 
1  3 
2  1 
2  3 
+0

這不起作用 - 在這種形式中使用不同的特徵會失去序列的獨特性,我只需要在時間之後合併類似的事件。如果序列是2 2 2 4 4 2 2,那麼我需要2 4 2. – Martin 2010-03-22 13:50:12

0

我比較喜歡COUNT < - > GROUP BY超過DISTINCT

SELECT Person, Event, COUNT(Time) Amount FROM Table GROUP BY Person, Event ORDER BY COUNT(Time) DESC 
+0

返回錯誤結果。輸出應該是(1,2)(1,4)然後(1,2)這種方法消除所有重複 – 2010-03-22 14:03:09