SQL 累积不重复计数

Posted

技术标签:

【中文标题】SQL 累积不重复计数【英文标题】:SQL a cumulative distinct count 【发布时间】:2020-03-10 22:23:14 【问题描述】:

我有一个列出单个事件的 SQL 表,我正在尝试聚合以获取一组事件,如下所示。

id |Name | Date|
0  |A    |2018-05-08
1  |A    |2018-05-09
2  |B    |2018-05-11
3  |B    |2018-05-12
4  |A    |2018-05-17
5  |A    |2018-05-17
6  |A    |2018-05-18
7  |C    |2018-05-25
8  |C    |2018-05-26
9  |B    |2018-05-27

变成:

Name|Group
|A  |1
|B  |2
|A  |3
|C  |4
|B  |5

我相信这是某种形式的 Count(),然后是 OVER BY,这总是让我感到困惑。我不知道我什至会数什么,因为很少将这些名称组合在一起。到目前为止,我有以下内容:

select
    Name
    ,Count(Name)
from table
Group BY
    Name

【问题讨论】:

【参考方案1】:

没有理由认为这是一个孤岛问题。我的意思是,它是,但有一个更简单的解决方案。

在这种情况下,使用lag()row_number()

select name, row_number() over (order by date, id) as grp
from (select t.*,
             lag(name) over (order by date, id) as prev_name
      from t
     ) t
where prev_name is null or prev_name <> name;

【讨论】:

【参考方案2】:

这是一个间隙和孤岛问题,您希望将“相邻”行组合在一起。

一种方法依赖于行号之间的差异来识别组。如果id 不断增加1,请考虑:

select 
    name,
    row_number() over(partition by name, id - rn order by min(date)) grp
from (
    select
        t.*,
        row_number() over(partition by name order by date) rn
    from mytable t
) t
group by name, id - rn
order by grp

否则,我们可以用row_number()生成id

select 
    name,
    row_number() over(partition by name, rn1 - rn2 order by min(date)) grp
from (
    select
        t.*,
        row_number() over(order by date) rn1,
        row_number() over(partition by name order by date) rn2
    from mytable t
) t
group by name, rn1 - rn2
order by grp

【讨论】:

这得到了我想要的,但我应该指定。有没有按日期订购的方法? @JackArmstrong:order by min(date). 按 min(date) 而非 grp 排序。我还在整个 select*from 中包含了 max(date),就像 max(date) 一样。

以上是关于SQL 累积不重复计数的主要内容,如果未能解决你的问题,请参考以下文章

重复的累积计数

每个值的累积计数[重复]

MySQL 抛出“java.sql.SQLException:列计数与第 1 行的值计数不匹配”[重复]

SQL Server - 每季度不同客户的运行计数

错误列计数不计算第 1 行的计数 [重复]

SQL查找不同值计数,2次重复值计数,3次重复值计数等