序列中的最大出现次数(高级间隙和孤岛问题)

Posted

技术标签:

【中文标题】序列中的最大出现次数(高级间隙和孤岛问题)【英文标题】:Maximum occurrence in sequence (advanced gaps and island problem) 【发布时间】:2021-05-27 17:19:58 【问题描述】:

对于human 中的每个hid,我需要用flag=1 计算事件的最大连续发生次数。序列是按日期生成的。

有一个我的表的例子:


    CREATE TABLE max_in_row
        ([hit_finish_dttm] varchar(13), [hid] varchar(13), [agent_login] varchar(57), [flg_no_talk] int)
    ;
    
    INSERT INTO max_in_row
        ([hit_finish_dttm], [hid], [agent_login], [flg_no_talk])
    VALUES
        ('2020-03-01', 'EQERR13', 'Dmitrii', 0),
        ('2020-03-02', 'EQERR13', 'Dmitrii', 1),
        ('2020-03-03', 'EQERR13', 'Dmitrii', 1),
        ('2020-03-01', 'RR13EQE', 'Dmitrii', 0),
        ('2020-03-02', 'RR13EQE', 'Dmitrii', 1),
        ('2020-03-03', 'RR13EQE', 'Dmitrii', 0),
        ('2020-03-04', 'RR13EQE', 'Dmitrii', 0),
        ('2020-03-05', 'RR13EQE', 'Dmitrii', 1),
        ('2020-03-06', 'RR13EQE', 'Dmitrii', 1),
        ('2020-03-07', 'RR13EQE', 'Dmitrii', 0),
        ('2020-03-01', 'EQERR13', 'Alex', 1),
        ('2020-03-02', 'EQERR13', 'Alex', 1),
        ('2020-03-03', 'EQERR13', 'Alex', 0),
        ('2020-03-04', 'EQERR13', 'Alex', 1),
        ('2020-03-05', 'EQERR13', 'Alex', 1),
        ('2020-03-06', 'EQERR13', 'Alex', 1),
        ('2020-03-02', 'RR13EQE', 'Alex', 1),
        ('2020-03-03', 'RR13EQE', 'Alex', 0),
        ('2020-03-04', 'RR13EQE', 'Alex', 1)
    ;

我希望在下一张桌子上收到结果:

Dmitrii | EQERR13 | 2
Dmitrii | RR13EQE | 2
Alex    | EQERR13 | 3
Alex    | RR13EQE | 1

我确实试图克服row_number(order by date) - row_number(partition by human, hid, flag order by flag) 的问题,但我不知道为什么它不起作用。

非常感谢!

【问题讨论】:

您的问题被标记为 Postgres 但示例代码是 SQL Server。 @GordonLinoff 完成 【参考方案1】:

您可以使用以下方法获取各个组:

select hid, agent_login, count(*)
from (select mir.*,
             row_number() over (partition by hid, agent_login order by hit_finish_dttm) as seqnum
      from max_in_row mir
      where flg_no_talk = 1
     ) mir
group by hid, agent_login, dateadd(day, -seqnum, hit_finish_dttm);

然后再聚合一次结果:

select hid, agent_login, max(cnt)
from (select hid, agent_login, count(*) as cnt
      from (select mir.*,
                   row_number() over (partition by hid, agent_login order by hit_finish_dttm) as seqnum
            from max_in_row mir
            where flg_no_talk = 1
           ) mir
      group by hid, agent_login, dateadd(day, -seqnum, hit_finish_dttm)
     ) ha
group by hid, agent_login;

Here 是一个使用 SQL Server 的 dbfiddle。除了日期函数外,Postgres 中的代码是相同的,但您的表创建代码适用于 SQL Server。

【讨论】:

为什么我们需要dateadd(day, -seqnum, hit_finish_dttm)?是否可以为 Postgres 重写 dateadd 函数? 是否可以在 Postgres 中做同样的事情? @VemenBusat 。 . .在 Postgres 中,它是hit_finish_dttm - seqnum * interval '1 day' 我收到关于类型的错误。为 Postgres (dbfiddle.uk/…) 创建表。如果您有任何想法,将不胜感激地听取他们的意见 @VemenBusat 。 . .不要将日期存储为字符串:dbfiddle.uk/….

以上是关于序列中的最大出现次数(高级间隙和孤岛问题)的主要内容,如果未能解决你的问题,请参考以下文章

基于列序列的间隙和孤岛查询/重置行数

分组依据基于 Redshift 中的后续标志(间隙和孤岛问题)

如何为间隙和孤岛问题编写查询?

间隙和孤岛 SQL 错误

按月、日、小时+间隙和孤岛问题分组

Oracle 排序间隙和孤岛查询