在有序数据集中指定连续相等值的组
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.
【讨论】:
以上是关于在有序数据集中指定连续相等值的组的主要内容,如果未能解决你的问题,请参考以下文章