按组排序的2列的表格,编号:
group_id | number
---------+--------
1 | 101
1 | 102
1 | 103
1 | 106
2 | 104
2 | 105
2 | 107
我应该编写什么SQL查询来获得以下输出:
group_id | number_from | number_to | total
---------+-------------+------------+-------
1 | 101 | 103 | 3
1 | 106 | 106 | 1
2 | 104 | 105 | 2
2 | 107 | 107 | 1
答案 0 :(得分:1)
我用它作为示例表:
create table temp (id int, val int)
insert into temp values (1,101),(1,102),(2,102),(2,104),(2,107)
insert into temp values (2,103)
insert into temp values (2,105)
insert into temp values (2,108)
insert into temp values (2,110)
这就是你想要的:
select t1id,cnt, min(t1val) as min, max(t1val), count(t1val)
from (
select tt1.*,
(select count (*) from
(
select t1.id as t1id,
t1.val as t1val,
(select val from temp t2 where t1.id = t2.id and t2.val = t1.val+1 ) as t2val,
row_number() over (order by t1.id, t1.val ) as rn
from temp t1
) tt2
where tt2.t2val is null and tt2.rn < tt1.rn
) cnt
from (
select t1.id as t1id,
t1.val as t1val,
(select val from temp t2 where t1.id = t2.id and t2.val = t1.val+1 ) as t2val,
row_number() over (order by t1.id, t1.val ) as rn
from temp t1
) tt1
)ttt1
group by t1id, cnt
order by t1id, min
更新:修复了表格未分类的错误)
答案 1 :(得分:1)
以下是脚本
create table Temp(A int,B int);
insert into temp values (1,101);
insert into temp values (1,102);
insert into temp values (1,103);
insert into temp values (1,106);
insert into temp values (2,104);
insert into temp values (2,105);
insert into temp values (2,107);
Select T2.A "group_id",
Min(T2.B) "number_from",
Max(T2.B) "number_to",
Max(T2.E) "total"
from
(
select *,(B-C) D,
rank() over
(PARTITION by T.A,(B-C) order by T.A,T.B) E,
rank() over
(order by T.A,(B-C)) F
from
(select A,B,row_number()
over (order by (select 0)) C
from temp) T
) T2
group by T2.A,T2.D,T2.F
order by 1,2
答案 2 :(得分:1)
WITH RECURSIVE rope AS (
SELECT i1.id AS low
, i1.id AS high
, i1.grp AS grp
, 1::integer AS cnt
FROM islands i1
-- no left neighbor
WHERE NOT EXISTS ( SELECT * FROM islands x WHERE x.grp = i1.grp AND x.id = i1.id-1)
UNION ALL
SELECT ch.low AS low
, i2.id AS high
, i2.grp AS grp
, 1+ch.cnt AS cnt
FROM islands i2
-- connect to left neighbor
JOIN rope ch ON i2.grp = ch.grp AND i2.id = ch.high+1
)
SELECT * FROM rope r
-- suppress subchains
WHERE NOT EXISTS (
SELECT * FROM rope nx
WHERE nx.low = r.low AND nx.cnt > r.cnt
)
;