我有完整的数据
表t1:
╔════╦═════════╦══════════════════╗
║ id ║ name ║ dt ║
╠════╬═════════╬══════════════════╣
║ 1 ║ name1 ║ 05/05/2016 10:00 ║
║ 2 ║ name2 ║ 07/05/2016 10:00 ║
║ 3 ║ name1 ║ 08/05/2016 10:00 ║
║ 4 ║ name1 ║ 09/05/2016 10:00 ║
╚════╩═════════╩══════════════════╝
我希望'按顺序分组'或标记每个具有相同名称的'连续'组
这样的事情
╔════════╦════════════════════════════════╦══════════════════════════════╦════════╗
║ name ║ min dt ║ max dt ║ agg id ║
╠════════╬════════════════════════════════╬══════════════════════════════╬════════╣
║ name1 ║ 05/05/2016 10:00 ║ 05/05/2016 10:00 ║ {1} ║
║ name2 ║ 07/05/2016 10:00 ║ 07/05/2016 10:00 ║ {2} ║
║ name1 ║ 08/05/2016 10:00 ║ 09/05/2016 10:00 ║ {3,4} ║
╚════════╩════════════════════════════════╩══════════════════════════════╩════════╝
或类似的东西
╔═══════════╦════╦═════════╦══════════════════╗
║ group id ║ id ║ name ║ dt ║
╠═══════════╬════╬═════════╬══════════════════╣
║ 1 ║ 1 ║ name1 ║ 05/05/2016 10:00 ║
║ 2 ║ 2 ║ name2 ║ 07/05/2016 10:00 ║
║ 3 ║ 3 ║ name1 ║ 08/05/2016 10:00 ║
║ 3 ║ 4 ║ name1 ║ 09/05/2016 10:00 ║
╚═══════════╩════╩═════════╩══════════════════╝
在postgres 9.4中有什么可能吗?
thx michal
答案 0 :(得分:1)
一种方法使用lag()
查看名称是否已更改。然后做一个该值的累积和:
select t.*,
sum(case when name = prev_name then 0 else 1 end) over (order by dt) as grp
from (select t.*,
lag(name) over (order by dt) as prev_name
from t1 t
) t;
为了获得最小值和最大值的聚合,我更喜欢行号方法的差异:
select name, min(dt), max(dt)
from (select t.*,
(row_number() over (order by dt) -
row_number() over (partition by name order by dt)
) as grp
from t1 t
) t
group by grp, name;
要了解发生的情况,最好使用单独的行号运行子查询。根据我的经验,当你看到序列及其差异时,你会有一个“啊哈”时刻。