Postgresql, объеденить последовательные числа через тире, наименьшее тире наибольшее

Столбец №3 сгруппирован по столбцу №1 и столбцу №2. На дубликаты не нужно обращать внимание их можно все убрать.

Нужно сделать так чтобы в столбце №3, который сгруппирован по столбцу №1 и столбцу №2. Числа, которые идут по порядку были записаны в сокращенной форме, а именно, "1,2,3,4,5,9,10,11,12" -> "1-5, 9-12" и так далее. Пробовал функции lag и lead, то есть делать дополнительные столбцы, в которых числа получались смещены относительно столбца nomkvr, но я не знаю как и что можно с их помощью дальше рассчитать. И вообще не знаю, на сколько это реально сделать в одном лишь postgresql. Спасибо!


Ответы (1 шт):

Автор решения: Akina

Пример объединения:

CREATE TABLE test (id INT);
INSERT INTO test VALUES (1), (2), (3), (4), (5), (9), (10), (11), (12), (20);

WITH 
cte1 AS ( SELECT id, id - ROW_NUMBER() OVER (ORDER BY id) grp
          FROM test ),
cte2 AS ( SELECT CASE WHEN MIN(id) < MAX(id)
                      THEN MIN(id)::text || '-' || MAX(id)::text
                      ELSE MIN(id)::text
                      END single_range
          FROM cte1 
          GROUP BY grp
          ORDER BY grp )
SELECT STRING_AGG(single_range, ', ') ranges_list
FROM cte2;
| ranges_list   |
| :------------ |
| 1-5, 9-12, 20 |

db<>fiddle here

→ Ссылка