sql—聚合数,有些在范围内

gc0ot86w  于 2021-07-24  发布在  Java
关注(0)|答案(2)|浏览(421)

我有一张table tab1 在我的数字列中使用以下值 c1 :

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 13
  12. 18

我想回来

  1. 1-5
  2. 6-10
  3. 13
  4. 18

以下查询在mysql中执行成功,但在postgresql中执行不成功:

  1. select distinct
  2. case
  3. when c1 between 1 and 5 then '1-5'
  4. when c1 between 6 and 9 then '6-10'
  5. else c1
  6. end as 'c1'
  7. from tab1;
z9ju0rcb

z9ju0rcb1#

相同的查询在修复语法错误和正确的强制转换后在postgres中工作:

  1. SELECT DISTINCT
  2. CASE WHEN c1 BETWEEN 1 AND 5 THEN '1-5'
  3. WHEN c1 BETWEEN 6 AND 9 THEN '6-10'
  4. ELSE c1::text END AS c1
  5. FROM tab1;

结果必须是字符串类型- text 是postgres的首选类型。但按字符串表示法排序对数字没有好处。因此,我建议采用这种方法进行适当的分类:

  1. SELECT CASE WHEN c1 BETWEEN 1 AND 5 THEN '1-5'
  2. WHEN c1 BETWEEN 6 AND 9 THEN '6-10'
  3. ELSE c1::text END AS new_c1 -- avoid duplicate of source name
  4. FROM tab1 t
  5. GROUP BY new_c1
  6. ORDER BY min(t.c1);

db<>在这里摆弄

展开查看全部
gpfsuwkq

gpfsuwkq2#

如果我理解正确,您将使用两个聚合级别。第一个得到范围:

  1. select min(c1), max(c1)
  2. from (select t.*, row_number() over (order by c1) as seqnum
  3. from t
  4. ) t
  5. group by c1 - seqnum;

然后,第二种方法重新聚合:

  1. select string_agg(range, ',' order by min_c1)
  2. from (select (case when min(c1) <> max(c1) then min(c1) || '-' || max(c1) else min(c1)::text end) as range, min(c1) as min_c1
  3. from (select t.*, row_number() over (order by c1) as seqnum
  4. from t
  5. ) t
  6. group by c1 - seqnum
  7. ) x

这里有一个db<>小提琴说明了这个逻辑的工作原理。

展开查看全部

相关问题