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

т.е. если номера идут списком 4525345345345345,4525345345345346,4525345345345347 группируется в диапазон 4525345345345345-4525345345345347, далее следующий диапазон
если номер в диапазоне один то передается одним номером
...
Рейтинг: 0 / 0
16.10.2014, 21:00:14
    #38779122
pgsql190
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранимая процедура для группировки номеров
Есть какие то типовые примеры реализации такой задачи или соображения как написать ?
...
Рейтинг: 0 / 0
17.10.2014, 00:20:57
    #38779246
V&N
V&N
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранимая процедура для группировки номеров
pgsql190 , lag+with recursive+distinct on.
из диапазона номеров дерево, и т.д.
...
Рейтинг: 0 / 0
17.10.2014, 00:59:36
    #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
17.10.2014, 05:28:12
    #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
17.10.2014, 05:56:46
    #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
17.10.2014, 11:07:36
    #38779550
V&N
V&N
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Хранимая процедура для группировки номеров
Добрый Э - Эх, да так проще, чёт-то меня занесло, ещё и супер тормоза с массивом предложил.
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Хранимая процедура для группировки номеров / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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