powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Хранимая процедура для группировки номеров
7 сообщений из 7, страница 1 из 1
Хранимая процедура для группировки номеров
    #38779121
pgsql190
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
есть таблица с номерами http://dl1.joxi.net/drive/0004/3643/302651/141016/046b8a208c.jpg
нужно получить список содержащий непрерывные диапазоны

т.е. если номера идут списком 4525345345345345,4525345345345346,4525345345345347 группируется в диапазон 4525345345345345-4525345345345347, далее следующий диапазон
если номер в диапазоне один то передается одним номером
...
Рейтинг: 0 / 0
Хранимая процедура для группировки номеров
    #38779122
pgsql190
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть какие то типовые примеры реализации такой задачи или соображения как написать ?
...
Рейтинг: 0 / 0
Хранимая процедура для группировки номеров
    #38779246
V&N
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
V&N
Гость
pgsql190 , lag+with recursive+distinct on.
из диапазона номеров дерево, и т.д.
...
Рейтинг: 0 / 0
Хранимая процедура для группировки номеров
    #38779253
V&N
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
V&N
Гость
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
with recursive parse_tree (depth, id, parent_id, path) 
  as (select 0, parent.id, parent.parentid, array[id]
        from (select id, 
                     case when id - lag(id) over (order by id) = 1 
                          then lag(id) over (order by id) 
                      end as parentid  
                from unnest('{1,2,3,4,5,6,7,9,10,null,4525345345345345,4525345345345346,4525345345345347,4525345345345348,4525345345345350,4525345345345356,4525345345345357}'::bigint[]) as table_range_numbers(id)) as parent
       where parentid is null
       union all
      select parent.depth + 1, 
             child.id, 
             child.parentid,
             parent.path ||child.id
        from parse_tree parent
        join (select id, 
                     case when id - lag(id) over (order by id) = 1 
                          then  lag(id) over (order by id) 
                      end as parentid  
                from unnest('{1,2,3,4,5,6,7,9,10,null,4525345345345345,4525345345345346,4525345345345347,4525345345345348,4525345345345350,4525345345345356,4525345345345357}'::bigint[]) as table_range_numbers(id)) as child on child.parentid = parent.id)
--select * from parse_tree
select path[1] as min_id, path[array_upper(path, 1)] as max_id, array_length(path,1) as cnt_item from (
select distinct on (path[1]) *
from parse_tree
order by path[1], path desc) as foo


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
      min_id      |      max_id      | cnt_item 
------------------+------------------+----------
                1 |                7 |        7                                                                                                                             
                9 |               10 |        2                                                                                                                             
 4525345345345345 | 4525345345345348 |        4                                                                                                                             
 4525345345345350 | 4525345345345350 |        1                                                                                                                             
 4525345345345356 | 4525345345345357 |        2                                                                                                                             
                  |                  |        1                                                                                                                             
(6 rows)           
...
Рейтинг: 0 / 0
Хранимая процедура для группировки номеров
    #38779294
V&N,

всё гораздо-гораздо проще... достаточно сгруппировать данные по разности между "номером" и row_number-ом:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
--
-- Тестовый набор данных:
with
  t(number) as
    (
      select i
        from  unnest('{1,2,3,4,5,6,7,9,10,null,4525345345345345,4525345345345346,4525345345345347,4525345345345348,4525345345345350,4525345345345356,4525345345345357}'::bigint[]
                    ) as t(i)
    )
--
-- Основной запрос:
select min(number) as min_num, max(number) as max_num, count(1) as cnt
  from (
         select number,
                number - row_number() over(order by number) as grp_id
           from t
       ) as v0
 group by grp_id
 order by min_num;

      min_num     |      max_num     |      cnt 
------------------+------------------+----------
                1 |                7 |        7                                                                                                                             
                9 |               10 |        2                                                                                                                             
 4525345345345345 | 4525345345345348 |        4                                                                                                                             
 4525345345345350 | 4525345345345350 |        1                                                                                                                             
 4525345345345356 | 4525345345345357 |        2                                                                                                                             
                  |                  |        1                                                                                                                             
(6 rows)     

on-line проверка на sqlfiddle.com
...
Рейтинг: 0 / 0
Хранимая процедура для группировки номеров
    #38779298
V&N,

кстати, если уж на лагах заморачиваться, то можно реализовать так называемый START_OF_GROUP-метод:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
--
-- Тестовый набор данных:
with
  t(number) as
    (
      select i
        from  unnest('{1,2,3,4,5,6,7,9,10,null,4525345345345345,4525345345345346,4525345345345347,4525345345345348,4525345345345350,4525345345345356,4525345345345357}'::bigint[]
                    ) as t(i)
    )
--
-- Основной запрос:
select min(number) as min_num, max(number) as max_num, count(1) as cnt
  from (
         select number, 
                sum(start_of_group) over(order by number) as grp_id
           from (
                  select number, 
                         case
                           when lag(number)over(order by number) + 1 = number 
                             then 0 
                           else 1 
                         end as start_of_group
                    from t
                ) v0
       ) as v1
 group by grp_id
 order by min_num

      min_num     |      max_num     |      cnt 
------------------+------------------+----------
                1 |                7 |        7                                                                                                                             
                9 |               10 |        2                                                                                                                             
 4525345345345345 | 4525345345345348 |        4                                                                                                                             
 4525345345345350 | 4525345345345350 |        1                                                                                                                             
 4525345345345356 | 4525345345345357 |        2                                                                                                                             
                  |                  |        1                                                                                                                             
(6 rows)

on-line проверка на sqlfiddle.com
...
Рейтинг: 0 / 0
Хранимая процедура для группировки номеров
    #38779550
V&N
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
V&N
Гость
Добрый Э - Эх, да так проще, чёт-то меня занесло, ещё и супер тормоза с массивом предложил.
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Хранимая процедура для группировки номеров
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]