2015-02-11 65 views
1

我需要根據其他列中的值計算連續的行。計數連續的行 - SQL Server 2008

當談到SQL時,我完全是新手 - 所以問一下如果有什麼不清楚的地方。

我有SQL Server 2008,因此LEAD()LAG()不起作用,與基於分區的窗口大小的OVER()相同。

實施例的數據集:

SLOT     Blocked 
------------------------------- 
2015-02-09 07:00:00.000 0 
2015-02-09 07:15:00.000 0 
2015-02-09 07:30:00.000 0 
2015-02-09 07:45:00.000 1 
2015-02-09 08:00:00.000 1 
2015-02-09 08:15:00.000 1 
2015-02-09 08:30:00.000 0 
2015-02-09 08:45:00.000 0 
2015-02-09 09:00:00.000 0 
2015-02-09 09:15:00.000 0 
2015-02-09 09:30:00.000 1 
2015-02-09 09:45:00.000 1 
2015-02-09 10:00:00.000 1 
2015-02-09 10:15:00.000 1 
2015-02-09 10:30:00.000 0 
2015-02-09 10:45:00.000 0 
2015-02-09 11:00:00.000 0 
2015-02-09 11:15:00.000 0 
2015-02-09 11:30:00.000 0 
2015-02-09 11:45:00.000 0 
2015-02-09 12:00:00.000 0 

的數據由SLOT排序。我想對分區where Blocked = 0上的行進行計數。

的結果集我想獲得:

SLOT     Blocked  RowNum 
------------------------------------------- 
2015-02-09 07:00:00.000 0   1 
2015-02-09 07:15:00.000 0   2 
2015-02-09 07:30:00.000 0   3 
2015-02-09 07:45:00.000 1   0 
2015-02-09 08:00:00.000 1   0 
2015-02-09 08:15:00.000 1   0 
2015-02-09 08:30:00.000 0   1 
2015-02-09 08:45:00.000 0   2 
2015-02-09 09:00:00.000 0   3 
2015-02-09 09:15:00.000 0   4 
2015-02-09 09:30:00.000 1   0 
2015-02-09 09:45:00.000 1   0 
2015-02-09 10:00:00.000 1   0 
2015-02-09 10:15:00.000 1   0 
2015-02-09 10:30:00.000 0   1 
2015-02-09 10:45:00.000 0   2 
2015-02-09 11:00:00.000 0   3 
2015-02-09 11:15:00.000 0   4 
2015-02-09 11:30:00.000 0   5 
2015-02-09 11:45:00.000 0   6 
2015-02-09 12:00:00.000 0   7 

提前感謝!

+0

只是像這種情況下的情況下,繼續進行條件遮光時= 0那麼ROW_NUMBER()OVER(PARTITION BY阻止ORDER BY封鎖)ELSE 0 END – mohan111 2015-02-11 09:17:19

+0

可能是我沒有澄清足夠 - 在「阻塞」列中找到1後,計數器必須重新啓動,如預期結果示例中所示。也許我的terribad英語是問題。 – TotallyNewb 2015-02-11 09:42:07

+0

數據中是否會有空白? – 2015-02-11 09:47:01

回答

2

對於SQL Server 2008,你可以解決它像這樣

SELECT Slot 
     ,Blocked 
     ,CASE WHEN Blocked = 0 
       THEN ROW_NUMBER() OVER 
       (PARTITION BY rt.RunningTotal ORDER BY Slot) 
      ELSE 0 END RowNum 
FROM Table1 t 
CROSS APPLY (SELECT ISNULL(SUM(Blocked), 0) RunningTotal 
      FROM Table1 
      WHERE Slot < t.Slot 
      ) rt 
ORDER BY Slot 

SQL小提琴(與你的表名稱替換表1):http://sqlfiddle.com/#!3/659a0/28

+0

似乎你的排名在前3排中排名不合格。在你的小提琴中相同 – 2015-02-11 11:27:34

+0

由於我的編輯建議被拒絕(???)我把它寫成註釋:你必須使用'SELECT ISNULL(SUM(Blocked),0)RunningTotal'來避免由第一行引起的自己的Partition缺少前面的行,因此RunningTotal爲null。 – flo 2015-02-11 11:28:20

+0

@flo,似乎有人拒絕了你所做的編輯建議。我現在編輯了,這解決了這個問題。 – 2015-02-11 11:39:20

3

由於您使用SQLSERVER 2008年,你需要使用row_number()結束。 計算有點複雜,但這個腳本會從2005年的sqlserver

;WITH CTE AS 
(
SELECT SLOT, row_number() over (order by SLOT)- 
row_number() over (partition by blocked order by SLOT) x, blocked 
FROM 
-- replace these lines with your real table 
--start test tabel 
(values 
(cast('2015-02-09 07:00:00.000' as datetime), 0) 
,('2015-02-09 07:15:00.000', 0),('2015-02-09 07:30:00.000', 0) 
,('2015-02-09 07:45:00.000', 1),('2015-02-09 08:00:00.000', 1) 
,('2015-02-09 08:15:00.000', 1),('2015-02-09 08:30:00.000', 0) 
,('2015-02-09 08:45:00.000', 0),('2015-02-09 09:00:00.000', 0) 
,('2015-02-09 09:15:00.000', 0),('2015-02-09 09:30:00.000', 1) 
,('2015-02-09 09:45:00.000', 1),('2015-02-09 10:00:00.000', 1) 
,('2015-02-09 10:15:00.000', 1),('2015-02-09 10:30:00.000', 0) 
,('2015-02-09 10:45:00.000', 0),('2015-02-09 11:00:00.000', 0) 
,('2015-02-09 11:15:00.000', 0),('2015-02-09 11:30:00.000', 0) 
,('2015-02-09 11:45:00.000', 0),('2015-02-09 12:00:00.000', 0)) x(SLOT,Blocked) 
-- end test tabel 
) 
SELECT 
    SLOT, 
    BLOCKED, 
    CASE WHEN blocked = 0 
    THEN 
     row_number() over (partition by x, blocked order by slot) 
    ELSE 0 end ROWNUMBER 
FROM cte 
ORDER BY slot 
工作
0

有趣的問題.. !!

我能夠使用這個代碼如下實現:

CREATE TABLE #TestTable(SLOT DATETIME,BLOCKED INT); 

    INSERT #TestTable(SLOT,BLOCKED) 
    VALUES 
    ('2015-02-09 07:00:00.000' ,0), 
    ('2015-02-09 07:15:00.000' ,0), 
    ('2015-02-09 07:30:00.000' ,0), 
    ('2015-02-09 07:45:00.000' ,1), 
    ('2015-02-09 08:00:00.000' ,1), 
    ('2015-02-09 08:15:00.000' ,1), 
    ('2015-02-09 08:30:00.000' ,0), 
    ('2015-02-09 08:45:00.000' ,0), 
    ('2015-02-09 09:00:00.000' ,0), 
    ('2015-02-09 09:15:00.000' ,0), 
    ('2015-02-09 09:30:00.000' ,1), 
    ('2015-02-09 09:45:00.000' ,1), 
    ('2015-02-09 10:00:00.000' ,1), 
    ('2015-02-09 10:15:00.000' ,1), 
    ('2015-02-09 10:30:00.000' ,0), 
    ('2015-02-09 10:45:00.000' ,0), 
    ('2015-02-09 11:00:00.000' ,0), 
    ('2015-02-09 11:15:00.000' ,0), 
    ('2015-02-09 11:30:00.000' ,0), 
    ('2015-02-09 11:45:00.000' ,0), 
    ('2015-02-09 12:00:00.000' ,0) 


    SELECT * 
    FROM #TestTable 
    ORDER BY SLOT 


    ;WITH TestTableVw AS 
    (SELECT SLOT,BLOCKED,ROW_NUMBER() OVER(ORDER BY SLOT) RNum 
    FROM #TestTable 
    ) 
    SELECT T.SLOT,T.BLOCKED,CASE WHEN T.BLOCKED=0 THEN V1.RNum-ISNULL((SELECT MAX(V2.RNum) FROM TestTableVw V2 WHERE V2.RNum<V1.RNum AND V2.BLOCKED=1),0) ELSE 0 END 
    FROM #TestTable T 
    JOIN TestTableVw V1 ON T.SLOT=V1.SLOT 

    DROP TABLE #TestTable; 

我希望這將有助於.. !!

謝謝,

Swapnil

+0

@TotallyNewb:檢查我提供的代碼是否適合您。我已使用您提供的示例數據對此進行了測試。該代碼生成問題中給出的預期輸出。 – Swapnil 2015-02-11 12:03:53