簡體   English   中英

SQL Server - 計算數據集中屬性更改的次數(非並發)

[英]SQL Server - Counting number of times an attribute in a dataset changes (non-concurrently)

我有一個查詢,根據事件是否在給定日期發生返回1或0。 這是按日期排序的。 基本上,一個簡單的結果集是:

Date         |  Type
---------------------
2010-09-27      1
2010-10-11      1
2010-11-29      0
2010-12-06      0
2010-12-13      1
2010-12-15      0
2010-12-17      0
2011-01-03      1
2011-01-04      0

我現在希望能夠做的是計算單獨的,非並發的'0'實例的數量 - 即計算有多少不同的0組出現。

在上面的例子中,答案應該是3(1組2,然后是另一組2,最后是1結束)。

希望上面的例子說明了我想要達到的目標。 我一直在尋找,但我發現很難簡潔地描述我在尋找什么,因此沒有找到任何相關的東西。

提前致謝,

玩笑

您可以在CTE中為每一行指定一個數字。 然后,您可以將表連接到自身以查找上一行。 知道前一行,您可以將前一行的次數加1,當前行為0.例如:

; with NumberedRows as
        (
        select  row_number() over (order by date) as rn
        ,       type
        from    YourTable
        )
select  sum(case when cur.type = 0 and IsNull(prev.type,1) = 1 then 1 end)
from    NumberedRows cur
left join    
        NumberedRows prev
on      cur.rn = prev.rn + 1

這是“島嶼”問題的變種。 我的第一個答案使用伊茨克奔甘的雙重row_number招有效地識別數據的連續組。 Type,Grp的組合標識數據中的每個島。

您可以在此處閱讀有關解決此問題的不同方法的更多信息。

;WITH T AS (
    SELECT  *,
            ROW_NUMBER() OVER(ORDER BY Date) -
            ROW_NUMBER() OVER(PARTITION BY Type ORDER BY Date)  AS Grp
    FROM    YourTable
)
SELECT  COUNT(DISTINCT Grp)
FROM    T
WHERE Type=0

我的第二個答案需要單次傳遞數據。 它不能保證工作,但其原理與許多人成功用於連接字符串而沒有問題的技術相同。

DECLARE @Count int = 0

SELECT @Count = CASE WHEN Type = 0 AND @Count <=0 THEN -@Count+1 
                     WHEN Type = 1 AND @Count > 0 THEN - @Count
                     ELSE @Count END

FROM YourTable
ORDER BY Date

SELECT ABS(@Count)

看看這個例子,使用Sql Server 2005+

DECLARE @Table TABLE(
        Date DATETIME,
        Type INT
)

INSERT INTO @Table SELECT '2010-09-27',1
INSERT INTO @Table SELECT '2010-10-11',1
INSERT INTO @Table SELECT '2010-11-29',0
INSERT INTO @Table SELECT '2010-12-06',0
INSERT INTO @Table SELECT '2010-12-13',1
INSERT INTO @Table SELECT '2010-12-15',0
INSERT INTO @Table SELECT '2010-12-17',0
INSERT INTO @Table SELECT '2011-01-03',1
INSERT INTO @Table SELECT '2011-01-04',0

;WITH Vals AS (
    SELECT  *,
            ROW_NUMBER() OVER(ORDER BY Date) ROWID
    FROM    @Table
)
SELECT  v.*
FROM    Vals v LEFT JOIN
        Vals vNext ON   v.ROWID + 1 = vNext.ROWID
WHERE   v.Type = 0
AND     (vNext.Type = 1 OR vNext.Type IS NULL)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM