组顺序整数postgres

时间:2018-08-30 22:10:42

标签: sql postgresql gaps-and-islands

我有一个查询返回:

1
2
5
7
8

我想将行分组为:

{1,2}
{5}
{7,8}

换句话说,我需要对顺序值进行分组。

有什么主意吗?

3 个答案:

答案 0 :(得分:3)

这是一个空白和空缺的问题。

您可以尝试创建行号,然后执行一些计算以生成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

Results

|  id |
|-----|
| 1,2 |
|   5 |
| 7,8 |

答案 1 :(得分:1)

根据对需求原因的回答,您正在尝试在表中查找损坏的序列。我会找出这样的差距。它没有明确地提供您所要求的内容,但是您所要求的内容却要复杂得多。

select col1 
from mytable S 
where not exists 
  (select col1 
   from mytable T 
   where T.col1 = S.col1 + 1)

这将返回间隔之前每组中连续的最后一个数字。

要准确地找到所需的内容,可以使用此表的结果和一些between语句来最终获得您的显式请求或更复杂的请求。不过,您可能会想得太多。

答案 2 :(得分:1)

看起来数组很合适,所以:

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);