具有下表: https://www.db-fiddle.com/f/avcRnMG6SVAoRuV5Rf4znF/2
create table tbl
(id integer,
start integer,
stop integer,
type integer);
INSERT INTO tbl values
(101, 1, 3, 10),
(101, 3, 6, 15),
(101, 6, 10, 17),
(101, 10, 40, 20),
(101, 40, 100, 20),
(101, 100, 200, 20),
(101, 200, 500, 55);
我想用边界值start
和stop
将具有相同值的相邻行分组。因此,结果应该是3行而不是type 20
101, 10, 200, 20
我尝试过类似的方法,但效果远非如此,那里有什么明智的,简短的解决方案吗?
SELECT
id,
case when lag(type) OVER (partition by id ORDER BY start ) = type
then lag(start) OVER (partition by id ORDER BY start) else start end as from
, case when lead(type) OVER (partition by id ORDER BY start ) = type
then lead(stop) OVER (partition by id ORDER BY start) else stop end as to
, type
from tbl
答案 0 :(得分:1)
可能会有更简洁的方法来执行此操作,但这就是我通常为此类要求解决的方式。您可以取消注释底部的其他选项,以查看每个步骤的作用。
type
的更改sum()
将行分配给分组,其中type
在连续的行中保持不变start
和stop
值
with changes as (
select *,
case
when lag(type) over (partition by id
order by start) = type then 0
else 1
end as changed
from tbl
), groups as (
select *,
sum(changed) over (partition by id
order by start) as grp
from changes
), combined as (
select id,
min(start) as start,
max(stop) as stop,
type
from groups
group by id, grp, type
)
--select * from changes order by start;
--select * from groups order by start;
select * from combined order by start;
答案 1 :(得分:1)
display:block
值似乎正在稳定增加,因此不再重复。因此,看起来简单的type
就足够了:
group by
如果类型可以散布,则需要使用更复杂的查询将其视为“隔岛问题”。