在有序数据集中指定连续相等值的组

Posted

技术标签:

【中文标题】在有序数据集中指定连续相等值的组【英文标题】:Designate groups of consecutive equal values in an ordered dataset 【发布时间】:2018-12-06 23:06:31 【问题描述】:

我正在尝试使输出如下所示。问题是我不能做 first_value 或 RANK 因为当我按事件分区和按时间排序时,它不会按那个顺序分解它们。我需要他们先按时间排序,然后每次分区。

【问题讨论】:

请显示示例输入、示例输出以及您尝试解决问题的查询。 所以我会有行事件和时间,需要弄清楚如何获得所需的行号。我试过: SELECT event, time, ROW_NUMBER () OVER( PARITITON BY event ORDER BY time ASC) as rn FROM TABLE 但这只是将所有事件按顺序排列,没有办法让它成为唯一的。跨度> 【参考方案1】:

已知解决方案之一

event发生变化时使用lag()标记行,使用累积sum()指定组,例如:

with my_table(event, time) as (
values 
    ('A', '12:01'),
    ('A', '12:02'),
    ('B', '12:03'),
    ('A', '12:04'),
    ('A', '12:05'),
    ('B', '12:06'),
    ('B', '12:07'),
    ('A', '12:08')
)

select 
    event, 
    time, 
    sum(change) over (order by time) as "desired row number"
from (
    select 
        event, 
        time, 
        (event is distinct from lag(event) over (order by time))::int as change
    from my_table
    ) s

 event | time  | desired row number 
-------+-------+--------------------
 A     | 12:01 |                  1
 A     | 12:02 |                  1
 B     | 12:03 |                  2
 A     | 12:04 |                  3
 A     | 12:05 |                  3
 B     | 12:06 |                  4
 B     | 12:07 |                  4
 A     | 12:08 |                  5
(8 rows)

自定义聚合

如果有这个功能就好了:

select *, group_number(event) over (order by time)
from my_table;

这可以通过自定义聚合来完成:

create type group_number_internal as (number int, lag text);

create or replace function group_number_transition(group_number_internal, anyelement)
returns group_number_internal language sql strict as $$
    select 
        case 
            when $2::text is distinct from $1.lag then $1.number+ 1 
            else $1.number 
        end, 
        $2::text
$$;

create or replace function group_number_final(group_number_internal)
returns int language sql as $$
    select $1.number
$$;

create aggregate group_number(anyelement) (
    sfunc = group_number_transition,
    stype = group_number_internal,
    finalfunc = group_number_final,
    initcond = '(0, null)'
);

Test it in rextester.

【讨论】:

以上是关于在有序数据集中指定连续相等值的组的主要内容,如果未能解决你的问题,请参考以下文章

在 Spark 中枚举连续相等值的块

c_cpp 用一个更大的值替换两个连续的相等值

C# 特性

如何计算数据集中的连续性?

创建具有不相等值列表的熊猫数据框

从 4000 多个图像集中过滤出 4 个完整的组