首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PostgreSQL查询:获取简洁的数字字符串

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

Stack Overflow用户
提问于 2020-06-26 02:59:02
回答 2查看 118关注 0票数 0

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

下面是表格:

代码语言:javascript
复制
create table tt8 (c1 numeric);
insert into tt8 values
(1),(2),(3),(6),(7),(8),(9),(12),(14);

使用表tt8,结果应该是这样的:

代码语言:javascript
复制
numbers
---------------
1-3,6-9,12,14

这是到目前为止我所知道的,但它给了我类型错误。我不认为这是正确的方式。

代码语言:javascript
复制
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;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-06-26 03:14:04

您可以使用间隔和孤岛方法,然后进行聚合。下面是获取组的方法:

代码语言:javascript
复制
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);

然后您可以将它们放入单个字符串中:

代码语言:javascript
复制
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;

Here是一个db<>fiddle。

票数 1
EN

Stack Overflow用户

发布于 2020-06-26 04:20:27

请尝试一下:

代码语言:javascript
复制
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()窗口函数来标记开始分组的行:

代码语言:javascript
复制
 c1 | new 
----+-----
  1 |   1
  2 |   0
  3 |   0
  6 |   1
  7 |   0
  8 |   0
  9 |   0
 12 |   1
 14 |   1
(9 rows)

groups使用带有隐式unbounded precedingsum()窗口函数为每行分配一个grpnum

代码语言:javascript
复制
 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()

代码语言:javascript
复制
 grpnum | low | high 
--------+-----+------
      3 |  12 |   12
      4 |  14 |   14
      2 |   6 |    9
      1 |   1 |    3
(4 rows)

textslowhigh范围转换为文本表示形式:

代码语言:javascript
复制
 grpnum | txt 
--------+-----
      3 | 12
      4 | 14
      2 | 6-9
      1 | 1-3
(4 rows)

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62582500

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档