powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Группировка идущих подряд повторяющихся строк
8 сообщений из 8, страница 1 из 1
Группировка идущих подряд повторяющихся строк
    #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
Группировка идущих подряд повторяющихся строк
    #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
Группировка идущих подряд повторяющихся строк
    #39526853
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
STFF start_of_group
...
Рейтинг: 0 / 0
Группировка идущих подряд повторяющихся строк
    #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
Группировка идущих подряд повторяющихся строк
    #39526982
Фотография mcwhite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic, присоединяюсь к благодарностям.
...
Рейтинг: 0 / 0
Группировка идущих подряд повторяющихся строк
    #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
Группировка идущих подряд повторяющихся строк
    #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
Группировка идущих подряд повторяющихся строк
    #39527037
Guest_group,

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


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