PostgreSQL查询:获取简明的数字字符串

PostgreSQL查询:获取简明的数字字符串,sql,database,postgresql,Sql,Database,Postgresql,获取一个简洁的数字字符串,例如,给定1,2,3,6,7,8,9,12,14,我们期望1-3,6-9,12,14 这是表格: create table tt8 (c1 numeric); insert into tt8 values (1),(2),(3),(6),(7),(8),(9),(12),(14); 使用表tt8,结果如下所示: numbers --------------- 1-3,6-9,12,14 这是我到目前为止得到的,但它给了我类型错误。 我认为这不是正确的方法 selec

获取一个简洁的数字字符串,例如,给定1,2,3,6,7,8,9,12,14,我们期望1-3,6-9,12,14

这是表格:

create table tt8 (c1 numeric);
insert into tt8 values
(1),(2),(3),(6),(7),(8),(9),(12),(14);
使用表tt8,结果如下所示:

numbers
---------------
1-3,6-9,12,14
这是我到目前为止得到的,但它给了我类型错误。 我认为这不是正确的方法

select c1,
case
when c1 = 1|2|3 then '1-3'
when c1 = 6|7|8|9 then '6-9'
else c1
end
from tt8;

您可以使用间隙和孤岛方法,然后进行聚合。以下内容获取了组:

select min(c1) || (case when count(*) = 1 then '' else '-' || max(c1) end)
from (select tt8.*, row_number() over (order by c1) as seqnum
      from tt8
     ) t
group by (c1 - seqnum);
然后可以将它们放入单个字符串中:

select string_agg(val, ',' order by min_c1)
from (select min(c1) || (case when count(*) = 1 then '' else '-' || max(c1) end) as val, min(c1) as min_c1
      from (select tt8.*, row_number() over (order by c1) as seqnum
            from tt8
           ) t
      group by (c1 - seqnum)
     ) t;

是一个数据字典。

您可以使用间隙和孤岛方法,然后进行聚合。以下内容获取了组:

select min(c1) || (case when count(*) = 1 then '' else '-' || max(c1) end)
from (select tt8.*, row_number() over (order by c1) as seqnum
      from tt8
     ) t
group by (c1 - seqnum);
然后可以将它们放入单个字符串中:

select string_agg(val, ',' order by min_c1)
from (select min(c1) || (case when count(*) = 1 then '' else '-' || max(c1) end) as val, min(c1) as min_c1
      from (select tt8.*, row_number() over (order by c1) as seqnum
            from tt8
           ) t
      group by (c1 - seqnum)
     ) t;

是一把小提琴。

请尝试一下:

with trans as (
  select c1, 
         case when lag(c1) over (order by c1) = c1 - 1 then 0 else 1 end as new
    from tt8
), groups as (
  select c1, sum(new) over (order by c1) as grpnum
    from trans
), ranges as (
  select grpnum, min(c1) as low, max(c1) as high
    from groups
   group by grpnum
), texts as (
  select grpnum, 
         case 
           when low = high then low::text 
           else low::text||'-'||high::text
         end as txt
    from ranges
)
select string_agg(txt, ',' order by grpnum) as answer
  from texts;

    answer     
---------------
 1-3,6-9,12,14
(1 row)
您可以更改最后一个查询以返回每个CTE的结果,以查看发生了什么

trans
使用
lag()

 c1 | new 
----+-----
  1 |   1
  2 |   0
  3 |   0
  6 |   1
  7 |   0
  8 |   0
  9 |   0
 12 |   1
 14 |   1
(9 rows)
groups
使用
sum()
窗口函数和隐式的
无界前置
为每一行分配一个
grpnum

 c1 | grpnum 
----+--------
  1 |      1
  2 |      1
  3 |      1
  6 |      2
  7 |      2
  8 |      2
  9 |      2
 12 |      3
 14 |      4
(9 rows)
ranges
将每个
groupnum
折叠为其
min()
max()

文本
范围转换为文本表示:

 grpnum | txt 
--------+-----
      3 | 12
      4 | 14
      2 | 6-9
      1 | 1-3
(4 rows)

字符串\u agg()
txt
值转换为逗号分隔的列表。

请尝试一下:

with trans as (
  select c1, 
         case when lag(c1) over (order by c1) = c1 - 1 then 0 else 1 end as new
    from tt8
), groups as (
  select c1, sum(new) over (order by c1) as grpnum
    from trans
), ranges as (
  select grpnum, min(c1) as low, max(c1) as high
    from groups
   group by grpnum
), texts as (
  select grpnum, 
         case 
           when low = high then low::text 
           else low::text||'-'||high::text
         end as txt
    from ranges
)
select string_agg(txt, ',' order by grpnum) as answer
  from texts;

    answer     
---------------
 1-3,6-9,12,14
(1 row)
您可以更改最后一个查询以返回每个CTE的结果,以查看发生了什么

trans
使用
lag()

 c1 | new 
----+-----
  1 |   1
  2 |   0
  3 |   0
  6 |   1
  7 |   0
  8 |   0
  9 |   0
 12 |   1
 14 |   1
(9 rows)
groups
使用
sum()
窗口函数和隐式的
无界前置
为每一行分配一个
grpnum

 c1 | grpnum 
----+--------
  1 |      1
  2 |      1
  3 |      1
  6 |      2
  7 |      2
  8 |      2
  9 |      2
 12 |      3
 14 |      4
(9 rows)
ranges
将每个
groupnum
折叠为其
min()
max()

文本
范围转换为文本表示:

 grpnum | txt 
--------+-----
      3 | 12
      4 | 14
      2 | 6-9
      1 | 1-3
(4 rows)

string_agg()
txt
值转换为逗号分隔的列表。

这对我不起作用,我在postgreSQL@JackDaniels95 . . . 我修正了打字错误,加了一把小提琴。这对我来说不管用,我会犯错误postgreSQL@JackDaniels95 . . . 我修正了打字错误,加了一把小提琴。