Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Группировка идущих подряд повторяющихся строк / 8 сообщений из 8, страница 1 из 1
27.09.2017, 08:16
    #39526846
Guest_group
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Группировка идущих подряд повторяющихся строк
Добрый день!
Подскажите как сгруппировать идущие подряд повторяющиеся строки и посчитать сумму и количество строк по ним.

Т.е. есть результат запроса:
IDVALSUMMA10110151102022100242210028221003311044221052333100533331005733310059333100
Надо сгруппировать идущие подряд повторяющиеся строки по VAL с сортировкой по ID
и вывести min(ID), max(ID), sum(SUMMA), count(*)

т.е. получить такую таблицу:
VAL min(ID) max(ID) sum(SUMMA) count(*)1101520222202830031333310122444410133352594004

min(ID) и max(ID) найти получилось:
Код: 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.
select t.val, t.min_id, t.max_id
  from (
        select t.*,
               t.id min_id,
               case when row_last = 1 then id else lead(t.id) over(order by t.id) end max_id
          from (
                select t.*,
                       decode(t.val, lag(t.val) over(order by t.id), 0, 1) row_first,
                       decode(t.val, lead(t.val) over(order by t.id), 0, 1) row_last
                  from (
                        select 10 id, 1   val, 10  summa from dual union all
                        select 15 id, 1   val, 10  summa from dual union all
                        select 20 id, 22  val, 100 summa from dual union all
                        select 24 id, 22  val, 100 summa from dual union all
                        select 28 id, 22  val, 100 summa from dual union all
                        select 33 id, 1   val, 10  summa from dual union all
                        select 44 id, 22  val, 10  summa from dual union all
                        select 52 id, 333 val, 100 summa from dual union all
                        select 53 id, 333 val, 100 summa from dual union all
                        select 57 id, 333 val, 100 summa from dual union all
                        select 59 id, 333 val, 100 summa from dual
                       )t
               )t
         where not (row_first = 0 and row_last = 0)
       )t
 where t.row_first = 1



а как получить сумму и количество?
...
Рейтинг: 0 / 0
27.09.2017, 08:28
    #39526849
Guest_group
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Группировка идущих подряд повторяющихся строк
Сумму и кол-во можно найти с помощью вложенных select-ов:
Код: 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 tab as (
  select 10 id, 1   val, 10  summa from dual union all
  select 15 id, 1   val, 10  summa from dual union all
  select 20 id, 22  val, 100 summa from dual union all
  select 24 id, 22  val, 100 summa from dual union all
  select 28 id, 22  val, 100 summa from dual union all
  select 33 id, 1   val, 10  summa from dual union all
  select 44 id, 22  val, 10  summa from dual union all
  select 52 id, 333 val, 100 summa from dual union all
  select 53 id, 333 val, 100 summa from dual union all
  select 57 id, 333 val, 100 summa from dual union all
  select 59 id, 333 val, 100 summa from dual
)
select t.val, t.min_id, t.max_id,
       (select sum(summa) from tab t1 where t1.val = t.val and t1.id between t.min_id and t.max_id) sum_summa,
       (select count(*) from tab t1 where t1.val = t.val and t1.id between t.min_id and t.max_id) count_row
  from (
        select t.*,
               t.id min_id,
               case when row_last = 1 then id else lead(t.id) over(order by t.id) end max_id
          from (
                select t.*,
                       decode(t.val, lag(t.val) over(order by t.id), 0, 1) row_first,
                       decode(t.val, lead(t.val) over(order by t.id), 0, 1) row_last
                  from tab t
               )t
         where not (row_first = 0 and row_last = 0)
       )t
 where t.row_first = 1



но такое решение не подходит, т.к. группируется большое кол-во строк, и с вложенными select-ами работает очень долго.
Нужно решение без них.
...
Рейтинг: 0 / 0
27.09.2017, 08:45
    #39526853
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Группировка идущих подряд повторяющихся строк
STFF start_of_group
...
Рейтинг: 0 / 0
27.09.2017, 09:34
    #39526885
Guest_group
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Группировка идущих подряд повторяющихся строк
Elic, Спасибо

Код: 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 tab as (
  select 10 id, 1   val, 10  summa from dual union all
  select 15 id, 1   val, 10  summa from dual union all
  select 20 id, 22  val, 100 summa from dual union all
  select 24 id, 22  val, 100 summa from dual union all
  select 28 id, 22  val, 100 summa from dual union all
  select 33 id, 1   val, 10  summa from dual union all
  select 44 id, 22  val, 10  summa from dual union all
  select 52 id, 333 val, 100 summa from dual union all
  select 53 id, 333 val, 100 summa from dual union all
  select 57 id, 333 val, 100 summa from dual union all
  select 59 id, 333 val, 100 summa from dual
)
select val,
       min(id) min_id,
       max(id) max_id,
       sum(summa) sum_summa,
       count(*) count_row
  from (
select t.*,
       sum(start_of_group) over(order by t.id) gr
  from (
        select t.*,
               decode(t.val, lag(t.val) over(order by t.id), 0, 1) start_of_group
          from tab t
       )t
)
group by val, gr
order by gr
...
Рейтинг: 0 / 0
27.09.2017, 11:04
    #39526982
mcwhite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Группировка идущих подряд повторяющихся строк
Elic, присоединяюсь к благодарностям.
...
Рейтинг: 0 / 0
27.09.2017, 11:15
    #39526988
Группировка идущих подряд повторяющихся строк
Guest_group,

чего-то ты сильно окольными путями пошел в решении своей простой задачки.
можно же было вот так:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
with tab as (
  select 10 id, 1   val, 10  summa from dual union all
  select 15 id, 1   val, 10  summa from dual union all
  select 20 id, 22  val, 100 summa from dual union all
  select 24 id, 22  val, 100 summa from dual union all
  select 28 id, 22  val, 100 summa from dual union all
  select 33 id, 1   val, 10  summa from dual union all
  select 44 id, 22  val, 10  summa from dual union all
  select 52 id, 333 val, 100 summa from dual union all
  select 53 id, 333 val, 100 summa from dual union all
  select 57 id, 333 val, 100 summa from dual union all
  select 59 id, 333 val, 100 summa from dual
)

select val, min(id) as min_id, max(id) as max_id, sum(summa) as sum_summs, count(1) as count_row
  from (
         select tab.*
              , row_number() over(partition by val order by id) - 
                row_number() over(order by id) as grp_id
           from tab
       ) v
 group by grp_id, val
 order by min(id);
...
Рейтинг: 0 / 0
27.09.2017, 12:01
    #39527030
Guest_group
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Группировка идущих подряд повторяющихся строк
Добрый Э - Эх, спасибо, но в твоём примере есть один нюанс,
у тебя один grp_id может быть одинаковый для разных val,
в моём примере он уникальный для всех групп

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
with tab as (
  select 10 id, 1   val, 10  summa from dual union all
  select 15 id, 1   val, 10  summa from dual union all
  select 20 id, 22  val, 100 summa from dual union all
  select 24 id, 22  val, 100 summa from dual union all
  select 28 id, 22  val, 100 summa from dual union all
  select 33 id, 1   val, 10  summa from dual union all
  select 44 id, 22  val, 10  summa from dual union all
  select 52 id, 333 val, 100 summa from dual union all
  select 53 id, 333 val, 100 summa from dual union all
  select 57 id, 333 val, 100 summa from dual union all
  select 59 id, 333 val, 100 summa from dual
)
select t.id, t.val,
       grp_id_val,
       sum(start_of_group) over(order by t.id) grp_id_global
  from (
        select t.*,
               decode(t.val, lag(t.val) over(order by t.id), 0, 1) start_of_group,
               row_number() over(order by id) - row_number() over(partition by val order by id) grp_id_val
          from tab t
       )t


IDVALGRP_ID_VALGRP_ID_GLOBAL101011510120222224222228222233 1 3 3 44 22 3 4 5233375533337557333755933375

В данном примере это не критично, но в некоторых задачах на это стоит обратить внимание.
...
Рейтинг: 0 / 0
27.09.2017, 12:11
    #39527037
Группировка идущих подряд повторяющихся строк
Guest_group,

сам по себе grp_id интереса не представляет, смотреть нужно только в паре с VAL, ибо GRP_ID - это номер группы внутри одного VAL. Именно поэтому GROUP BY идет по их паре.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Группировка идущих подряд повторяющихся строк / 8 сообщений из 8, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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