繁体   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