[英]Grouping Consecutive Rows in DB2
我在DB2中有一个表,如下所示:-
ID DESCRIPTION TYPE AMOUNT
-- ----------- ---- ------
1 Item 1 ONE 100
2 Item 2 ONE 50
3 Item 3 TWO 100
4 Item 4 TWO 50
5 Item 5 ONE 100
6 Item 6 TWO 50
7 Item 7 ONE 100
8 Item 8 TWO 50
9 Item 9 TWO 100
10 Item 10 ONE 50
我想将具有相同类型的连续行分组,因此它看起来如下:-
TYPE AMOUNT
---- ------
ONE 150 -- (ID 1,2)
TWO 150 -- (ID 3,4)
ONE 100 -- (ID 5)
TWO 50 -- (ID 6)
ONE 100 -- (ID 7)
TWO 150 -- (ID 8,9)
ONE 50 -- (ID 10)
请注意,最后一列只是为了指示汇总中包含哪些ID。
我宁愿使用查询而不是存储过程来执行此操作。
除非我错过我的猜测,否则可以使用双ROW_NUMBER()
常量表达式轻松完成此操作:
SELECT type, SUM(amount) AS amount
FROM (SELECT type, amount, id,
ROW_NUMBER() OVER(ORDER BY id)
- ROW_NUMBER() OVER(PARTITION BY type ORDER BY id) AS groupId
FROM tbl) grouped
GROUP BY groupId, type
ORDER BY groupId, MIN(id)
SQL小提琴示例
(感谢Brian的初步提琴设置)
...产生预期的结果。 请注意,必须使用MIN(id)
才能确保一致的排序顺序groupId
并不是唯一的,因此,某些ONE
或TWO
行可能最终会翻转。
附带说明一下,我不喜欢在id
列上排序,因为这样的id 唯一真正有用的就是唯一性 。 在行可能被更新或以其他方式重新解释的情况下尤其如此-您是否有类似insertedAt
时间戳之类的东西可用于排序?
认为我明白了:
with sub1 as
(select x.*,
case when chk is not null
then row_number() over(order by id)
else null
end as rn
from (select id,
description,
type,
amount,
case when lag(type, 1) over(order by id) <> type
then 'X'
else null
end as chk
from tbl
order by id) x)
select min(type),
sum(amount) as amount,
listagg(id, ', ') within group(order by id) as ids
from (select z.id, z.description, z.type, z.amount, y.rn
from sub1 z
cross join sub1 y
where z.rn is null
and y.rn = (select max(x.rn)
from sub1 x
where x.id < z.id
and x.rn is not null)
union all
select id, description, type, amount, rn
from sub1
where rn is not null
union all
select id, description, type, amount, 1
from sub1
where id < (select min(id) from sub1 where rn is not null)
order by id) x
group by rn
order by rn
我在Oracle中对其进行了测试,但它仅依赖于DB2拥有的with子句和window函数,因此它应该可以工作,即使有任何微小的修改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.