组顺序整数postgres
Group sequential integers postgres
我有一个查询 returns:
1
2
5
7
8
我想像这样对行进行分组:
{1,2}
{5}
{7,8}
换句话说,我需要对顺序值进行分组。
有什么想法吗?
这是一个缺口和孤岛问题。
您可以尝试制作行号,然后进行一些计算以制作 group by
编号。
CREATE TABLE T(
ID INT
);
INSERT INTO T VALUES (1);
INSERT INTO T VALUES (2);
INSERT INTO T VALUES (5);
INSERT INTO T VALUES (7);
INSERT INTO T VALUES (8);
查询 1:
WITH CTE AS (
SELECT Min(id) minid,MAX(ID) maxid
FROM (
SELECT ID,ID - ROW_NUMBER() OVER(ORDER BY ID) rn
FROM T
)t1
group by rn
)
SELECT (CASE WHEN minid = maxid
THEN CAST(maxid AS VARCHAR(50))
ELSE CONCAT(minid,',',maxid)
END) ID
FROM CTE
ORDER BY minid
| id |
|-----|
| 1,2 |
| 5 |
| 7,8 |
根据您对需求原因的回答,您正试图在 table 中找到损坏的序列。我会找出这样的差距。它没有明确地给你你所要求的,但你所要求的要复杂得多。
select col1
from mytable S
where not exists
(select col1
from mytable T
where T.col1 = S.col1 + 1)
这将 return 在间隔之前每组中的最后一个数字。
要准确获得您想要的结果,您可以使用此 table 和一些 between
语句的结果来最终获得您的明确请求或更复杂的内容。不过你可能想多了。
这看起来像一个数组是合适的,所以:
select array_agg(col order by col)
from (select t.*, row_number() over (order by col) as seqnum
from t
) t
group by (col - seqnum);
编辑:
如果您只想要开始和结束,请使用 max()
和 min()
:
select min(col), max(col)
from (select t.*, row_number() over (order by col) as seqnum
from t
) t
group by (col - seqnum);
我有一个查询 returns:
1
2
5
7
8
我想像这样对行进行分组:
{1,2}
{5}
{7,8}
换句话说,我需要对顺序值进行分组。
有什么想法吗?
这是一个缺口和孤岛问题。
您可以尝试制作行号,然后进行一些计算以制作 group by
编号。
CREATE TABLE T(
ID INT
);
INSERT INTO T VALUES (1);
INSERT INTO T VALUES (2);
INSERT INTO T VALUES (5);
INSERT INTO T VALUES (7);
INSERT INTO T VALUES (8);
查询 1:
WITH CTE AS (
SELECT Min(id) minid,MAX(ID) maxid
FROM (
SELECT ID,ID - ROW_NUMBER() OVER(ORDER BY ID) rn
FROM T
)t1
group by rn
)
SELECT (CASE WHEN minid = maxid
THEN CAST(maxid AS VARCHAR(50))
ELSE CONCAT(minid,',',maxid)
END) ID
FROM CTE
ORDER BY minid
| id |
|-----|
| 1,2 |
| 5 |
| 7,8 |
根据您对需求原因的回答,您正试图在 table 中找到损坏的序列。我会找出这样的差距。它没有明确地给你你所要求的,但你所要求的要复杂得多。
select col1
from mytable S
where not exists
(select col1
from mytable T
where T.col1 = S.col1 + 1)
这将 return 在间隔之前每组中的最后一个数字。
要准确获得您想要的结果,您可以使用此 table 和一些 between
语句的结果来最终获得您的明确请求或更复杂的内容。不过你可能想多了。
这看起来像一个数组是合适的,所以:
select array_agg(col order by col)
from (select t.*, row_number() over (order by col) as seqnum
from t
) t
group by (col - seqnum);
编辑:
如果您只想要开始和结束,请使用 max()
和 min()
:
select min(col), max(col)
from (select t.*, row_number() over (order by col) as seqnum
from t
) t
group by (col - seqnum);