簡體   English   中英

計算不同的分區

[英]Count distinct over partition by

我正在嘗試對按角色划分的名稱進行不同的計數。 因此,在下面的示例中:我有一個包含姓名和人員角色的表格。

我想要一個角色計數列,它給出該角色中不同人員的總數。 例如,角色經理出現了四次,但該角色只有 3 個不同的人 - Sam 在不同的日期再次出現。

如果我刪除日期列,它可以正常使用:

select
a.date,
a.Name,
a.Role,
count(a.Role) over (partition by a.Role) as Role_Count

from table a

group by a.date, a.name, a.role

包括日期列然后使它計算總角色而不是按不同的名稱(我知道我沒有在分區中標識)。 給4個經理和3個分析師。

我該如何解決?

所需的 output:

日期 姓名 角色 Role_Count
01/01 山姆 經理 3
02/01 山姆 經理 3
01/01 約翰 經理 3
01/01 經理 3
01/01 鮑勃 分析師 2
02/01 鮑勃 分析師 2
01/01 麥克風 分析師 2

當前 output:

日期 姓名 角色 Role_Count
01/01 山姆 經理 4
02/01 山姆 經理 4
01/01 約翰 經理 4
01/01 經理 4
01/01 鮑勃 分析師 3
02/01 鮑勃 分析師 3
01/01 麥克風 分析師 3

不幸的是, COUNT(DISTINCT不能用作 window 聚合。但我們可以使用DENSE_RANKMAX的組合來模擬它:

select

a.Name,
a.Role,
MAX(rnk) OVER (PARTITION BY date, Role) as Role_Count

from (
    SELECT *,
        DENSE_RANK() OVER (PARTITION BY date, Role ORDER BY Name) AS rnk
    FROM table
) a

如果Name可能有空值,那么我們需要考慮到這一點:

select

a.Name,
a.Role,
MAX(CASE WHEN Name IS NOT NULL THEN rnk END) OVER (PARTITION BY date, Role) as Role_Count

from (
    SELECT *,
        DENSE_RANK() OVER (PARTITION BY date, Role, CASE WHEN Name IS NULL THEN 0 ELSE 1 END ORDER BY Name) AS rnk
    FROM table
) a

不幸的是,SQL 服務器(以及其他數據庫)不支持COUNT(DISTINCT)作為 window function。 幸運的是,有一個簡單的技巧可以解決這個問題 - DENSE_RANK()的總和減去一:

select a.Name, a.Role,
       (dense_rank() over (partition by a.Role order by a.Name asc) +
        dense_rank() over (partition by a.Role order by a.Name desc) -
        1
       ) as distinct_names_in_role
from table a
group by a.name, a.role

暫無
暫無

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

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