簡體   English   中英

使用分區運行不同的計數

[英]Running Distinct Count with a Partition

對於以下數據,我想要一個按年分區的運行不同計數:

DROP TABLE IF EXISTS #FACT;
CREATE TABLE #FACT("Year" INT,"Month" INT, "Acc" varchar(5));
INSERT INTO #FACT
    values 
        (2015, 1, 'A'),
        (2015, 1, 'B'),
        (2015, 1, 'B'),
        (2015, 1, 'C'),
        (2015, 2, 'D'),
        (2015, 2, 'E'),
        (2015, 3, 'E'),
        (2016, 1, 'A'),
        (2016, 1, 'A'),
        (2016, 2, 'B'),
        (2016, 2, 'C');
SELECT * FROM #FACT;    

以下返回正確的答案,但是否有更簡潔的方法也有效?

WITH 
dnsRnk AS
(
    SELECT 
        "Year"
        , "Month"
        , DenseR  = DENSE_RANK() OVER(PARTITION BY "Year", "Month" ORDER BY "Acc")
    FROM #FACT
),
mxPerMth AS
(
    SELECT
        "Year"
        , "Month"
        , RunningTotal = MAX(DenseR)
    FROM dnsRnk
    GROUP BY 
        "Year"
        , "Month"
)
SELECT 
    "Year"
    , "Month"
    , X = SUM(RunningTotal) OVER (PARTITION BY "Year" ORDER BY "Month")
FROM mxPerMth
ORDER BY 
    "Year"
    , "Month";

以上返回以下內容 - 答案也應該返回完全相同的表:

在此處輸入圖片說明

如果您想要不同帳戶的運行計數:

SELECT f.*,
    sum(case when seqnum = 1 then 1 else 0 end) over (partition by year order by month) as cume_distinct_acc
FROM (
    SELECT 
        f.*
        ,row_number() over (partition by account order by year, month) as seqnum
    FROM #fact f
) f;

這會在出現的第一個月內對每個帳戶進行計數。

編輯:

哎呀。 以上不按年和月匯總,然后每年重新開始。 這是正確的解決方案:

SELECT 
    year
    ,month
    ,sum( sum(case when seqnum = 1 then 1 else 0 end)
        ) over (partition by year order by month) as cume_distinct_acc
FROM (
    SELECT 
        f.*
        ,row_number() over (partition by account, year order by month) as seqnum
    FROM #fact f
) f
group by year, month
order by year, month;

而且,SQL Fiddle 不起作用,但以下是一個示例:

with FACT as (
    SELECT yyyy, mm, account
    FROM (values 
        (2015, 1, 'A'),
        (2015, 1, 'B'),
        (2015, 1, 'B'),
        (2015, 1, 'C'),
        (2015, 2, 'D'),
        (2015, 2, 'E'),
        (2015, 3, 'E'),
        (2016, 1, 'A'),
        (2016, 1, 'A'),
        (2016, 2, 'B'),
        (2016, 2, 'C')) v(yyyy, mm, account)
)
SELECT 
    yyyy
    ,mm
    ,sum(sum(case when seqnum = 1 then 1 else 0 end)) over (partition by yyyy order by mm) as cume_distinct_acc
FROM (
    SELECT 
        f.*
        ,row_number() over (partition by account, yyyy order by mm) as seqnum
    FROM fact f
) f
group by yyyy, mm
order by yyyy, mm;

演示在這里:

;with cte as (
    SELECT yearr, monthh, count(distinct acc) as cnt  
    FROM #fact
    GROUP BY yearr, monthh
)
SELECT 
    yearr
    ,monthh
    ,sum(cnt) over (Partition by yearr order by yearr, monthh rows unbounded preceding ) as x
FROM cte

暫無
暫無

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

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