powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Пятничная задача: Красное и черное
25 сообщений из 176, страница 7 из 8
Пятничная задача: Красное и черное
    #40020272
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кобанчег
Последний отрезок ломает решения икстендера потому что до него дырка, но легко допиливается.
Ничего он не ломает, это провокация!
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020275
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кобанчег,

у икстендера есть главный/0 интервал покрывающий все, типа min()-x,max()+y цвета хаки
тогда дырок не будет

не знаю часть условия ли ето, или случайно

если я правильно понял то заливка уникальными цветами range_name

.....
stax
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020281
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax,

Да. У икстендера надо пустые интервалы выкинуть из результата.
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020597
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кобанчег
Challenge just for fun

Решить задачу отсюда
https://stackoverflow.com/questions/64137899/flatten-list-of-ranges-to-single-result-range-set

Не используя соединений или коррелированных подзапросов.

Ну и без завязывания на частные случаи. То есть
- границы не обязательно целочисленные - никакой генерации
- число приоритетов неограничено - никакого хардкодига
итд

У меня более одного варианта.


У меня число приоритетов до 38 попугаев, т.к. я не сумел listagg() использовать в оконном режиме.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
p as (
select c, x x1, lead(x) over (order by x ) x2 from (
  select c, x from (
    select c, lag(c) over (order by x) cp, x from (
      select chr(trunc(log(10,1+sum(c) over (order by x)))) c, x from (
        select  power(10,ascii(lvl)) c, x1 x from t union all
        select -power(10,ascii(lvl)) c, x2 x from t
      )
    )
  ) where nvl(c,'-') != nvl(cp,'-')
)
)
select * from p where x1 < x2 order by x1
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020602
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кобанчег
НеофитSQL
Нарушено условие задачи, интервалы одного уровня касаются.
Перечитай условие. Подумай ещё. Посмотри в чем фикс. Всё же было обсуждено.


Перечитал, действительно. О несоприкосновении говорилось в разминке, но не во второй задаче. С фиксом понятно.
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020611
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
НеофитSQL

У меня число приоритетов до 38 попугаев, т.к. я не сумел listagg() использовать в оконном режиме.


Оно таки и не работает с окнами..
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020643
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
О несоприкосновении говорилось
Изначально в разрезе красное/черное, а потом подразумевалсь в разрезе src/tgt.
Но Stax уточнил 22233313 .
Твой запрос поломало касание src и tgt - это допустимо.
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020656
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нарушено условие задачи, интервалы одного уровня касаются.

Stax
НеофитSQL
Жаль, критерий трудно определить объективно.

У меня получилось так.


должно быть две строки?

Код: 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.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
with t (x1, x2, c, flag) as
(
              select 10, 30, 'blue', 'src' from dual
union all select 20, 30, 'red', 'tgt' from dual
union all select 31, 35, 'red', 'tgt' from dual
)
,p as (
select * from (
  select x, flag, decode(z,'X1',c,'-') c, z
    from (select x1, x2+1 x2, c, flag from t) tt
 unpivot (x for z in (x1,x2))) 
 pivot (max(c) for flag in ('src' s,'tgt' t))
),
q as (
select x x1, lead(x) over (order by x) -1 x2, c from (
  select x, c, lag(c) over (order by x) cp from (
    select x, decode(s,'-',t,s) c from (
      select x,
             last_value(s ignore nulls) over (order by x) s,
             last_value(t ignore nulls) over (order by x) t
        from p
      )
    )
  )
 where c != nvl(cp,' ')
)
select x1,x2,c from q
 where x1 <= x2  
/

SQL> /

        X1         X2 C
---------- ---------- ----
        10         30 blue



.....
stax
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020663
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,

Да, верно.
Это заодно и объясняет почему тест производительности не выявил различий.
Данные были нагенерированы без таких случаев.
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020805
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пятница, господа!

Челендж еще активен
Кобанчег
Challenge just for fun

Решить задачу отсюда
https://stackoverflow.com/questions/64137899/flatten-list-of-ranges-to-single-result-range-set

Не используя соединений или коррелированных подзапросов.

Ну и без завязывания на частные случаи. То есть
- границы не обязательно целочисленные - никакой генерации
- число приоритетов неограничено - никакого хардкодига
итд

У меня более одного варианта.


Данные для тестирования
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
with ranges (name, range_start, range_end) as
(
select 'a', 0, 7 from dual
union all select 'b', 2, 4 from dual
union all select 'c', 1, 3 from dual
union all select 'd', 4, 6 from dual
union all select 'e', 3, 6 from dual
--
union all select 'x', 3, 3.1 from dual
union all select 'y', 3.5, 3.7 from dual
union all select 'z', 3.9, 5.1 from dual
union all select 'a', 8, 9 from dual
union all select 'a', 8, 9.9 from dual
)



Constraints
(name, range_start, range_end) - уникально
(range_end > range_start)
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020811
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Кобанчег
- число приоритетов неограничено
name может быть от a,...,z,aa,...,az,...,zzzzzzzzzzzzz?
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020813
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Кобанчег,

model, рекурсивные запросы?
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020815
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender
Кобанчег,

model, рекурсивные запросы?
Затрудняюсь представить как можно обойтись без джойна в рекурсивном члене.

Модель - конено, почему бы нет. Ну разве что итеративная модель - это не спортивно.
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020819
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender
Кобанчег
- число приоритетов неограничено
name может быть от a,...,z,aa,...,az,...,zzzzzzzzzzzzz?
Не вижу смысла ограничивать, но если с какими-то подобнми особенностями получается что-то изящное - интересно было бы посмотреть.
Ну на единичную длину закладываться не стоит.
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020831
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кобанчег
xtender
пропущено...
name может быть от a,...,z,aa,...,az,...,zzzzzzzzzzzzz?
Не вижу смысла ограничивать, но если с какими-то подобнми особенностями получается что-то изящное - интересно было бы посмотреть.
Ну на единичную длину закладываться не стоит.

имхо
удобнее было-б уровень задавать числами (int), цвет varchar2(хх)

....
stax
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020844
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax,

Мне кажется примерно индифферентно для чего делать max.
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020845
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кобанчег
Stax,

Мне кажется примерно индифферентно для чего делать max.

a
aa
ab
c
d
...
z

мне удобнее числа
и легче тестовые добавлять (+ не надо помнить алфавит)

в етой пятничной наверное менять не надо, у народа наработки уже на буквах

.....
stax
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020880
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Собственно варианты следующие.

Раз

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
select *
  from (select x, max(decode(y, 1, name)) name
          from (select *
                  from (select x, name, sum(r) r
                          from ranges unpivot(x for r in(range_start as '1', range_end as '-1'))
                         group by x, name)
                 model dimension by(x, name) measures(r, 0 y)
                 rules upsert all
                 (
                   y[x, for name in (select distinct name from ranges)] = sign(sum(r)[x <= cv(x), name = cv(name)])
                 ))
         group by x)
match_recognize
(
  order by x
  measures
    first(x) range_start,
    next(x) range_end,
    name name
  pattern (x+)
  define x as first(name) = name
)
order by 1, 2

for loop + upsert all помогает получить все имена для каждого перехода.
Дальше берем max и склеиваем с помощью MR.

for loop однако требует отдельного обращения к таблице. По идее Оракл это мог бы брать из памяти.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
------------------------------------------------------------------------
| Id  | Operation                                             | Name   |
------------------------------------------------------------------------
|   0 | SELECT STATEMENT                                      |        |
|   1 |  SORT ORDER BY                                        |        |
|   2 |   VIEW                                                |        |
|   3 |    MATCH RECOGNIZE SORT DETERMINISTIC FINITE AUTOMATON|        |
|   4 |     VIEW                                              |        |
|   5 |      HASH GROUP BY                                    |        |
|   6 |       VIEW                                            |        |
|   7 |        BUFFER SORT                                    |        |
|   8 |         SQL MODEL ORDERED                             |        |
|   9 |          HASH GROUP BY                                |        |
|  10 |           VIEW                                        |        |
|  11 |            UNPIVOT                                    |        |
|  12 |             TABLE ACCESS FULL                         | RANGES |
|  13 |          BUFFER SORT                                  |        |
|  14 |           HASH UNIQUE                                 |        |
|  15 |            TABLE ACCESS FULL                          | RANGES |
------------------------------------------------------------------------

22 rows selected.



Два

Получаем оригинальные и "нарезанные" интервалы.
Моделью возвращаем "нарезанные" с определенными новыми именами (return updated rows).
Последним шагом снова склеиваем через MR.

Код: 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.
25.
26.
27.
28.
select *
  from (select *
          from (select range_start, range_end, name, 'original' type
                  from ranges
                union all
                select x as range_start, lead(x) over(order by x) as range_end, null, 'derived'
                  from (select distinct x
                          from ranges unpivot(x for r in(range_start, range_end))))
  model
  return updated rows
  dimension by (range_start, range_end, type)
  measures (name)
  rules
  (
    name[range_start, range_end, 'derived'] = max(name)[range_start < cv(range_end), range_end > cv(range_start), type = 'original']
  )
)
match_recognize
(
  order by range_start
  measures
    first(range_start) range_start,
    range_end range_end,
    name name
  pattern (x+)
  define x as first(name) = name
)
order by 1, 2



Если заморочиться можно обойтись одним обращением к таблице + двойной UNPIVOT + MODEL + MATCH RECOGNIZE

Код: 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.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
select *
  from (select *
          from (select name,
                       type,
                       x1 range_start,
                       nvl(x2, lead(x1) over(partition by type order by x1)) range_end
                  from (select distinct name, x x1, x2, type
                          from (select decode(type, 'original', name) name,
                                       range_start,
                                       decode(type, 'derived', range_end) range_end,
                                       decode(type, 'original', range_end) x2,
                                       type
                                  from (select r.*, 1 dummy from ranges r)
                                  unpivot (dummy for type in (dummy as 'original', dummy as 'derived'))
                                )
                          unpivot (x for r in (range_start, range_end))
                        )
                )
          model
          return updated rows
          dimension by (range_start, range_end, type)
          measures (name)
          rules
          (
            name[range_start, range_end, 'derived'] = max(name)[range_start < cv(range_end), range_end > cv(range_start), type = 'original']
          )
       )
match_recognize
(
  order by range_start
  measures
    first(range_start) range_start,
    range_end range_end,
    name name
  pattern (x+)
  define x as first(name) = name
)
order by 1, 2


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
------------------------------------------------------------------------
| Id  | Operation                                             | Name   |
------------------------------------------------------------------------
|   0 | SELECT STATEMENT                                      |        |
|   1 |  SORT ORDER BY                                        |        |
|   2 |   VIEW                                                |        |
|   3 |    MATCH RECOGNIZE SORT DETERMINISTIC FINITE AUTOMATON|        |
|   4 |     VIEW                                              |        |
|   5 |      BUFFER SORT                                      |        |
|   6 |       SQL MODEL ORDERED                               |        |
|   7 |        VIEW                                           |        |
|   8 |         WINDOW SORT                                   |        |
|   9 |          VIEW                                         |        |
|  10 |           HASH UNIQUE                                 |        |
|  11 |            VIEW                                       |        |
|  12 |             UNPIVOT                                   |        |
|  13 |              VIEW                                     |        |
|  14 |               UNPIVOT                                 |        |
|  15 |                TABLE ACCESS FULL                      | RANGES |
------------------------------------------------------------------------


...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020882
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
with ranges (name, range_start, range_end) as
(
          select 'a', 0, 7 from dual
union all select 'b', 2, 4 from dual
union all select 'c', 1, 3 from dual
union all select 'd', 4, 6 from dual
union all select 'e', 3, 5 from dual
),
p (r,c,a,b) as (
          select dense_rank() over (order by name), name, range_start, range_end   from ranges
union all select dense_rank() over (order by name), null, -100500,     range_start from ranges
union all select dense_rank() over (order by name), null, range_end,   +100500     from ranges
),
cte (n, clr, x, y) as (
select max(r)+1, null, -100500, +100500 from p union all
select n-1, c, greatest(x,a), least(y,b)
  from cte e, p 
 where n > 1 and r=n-1 and clr is null and x < y
)
select * from cte where x < y and clr is not null order by x



Вместо 100500 можно +/- бесконечность (быстрее) или min(start)/max(end) (медленнее).
Приоритет вычисляется по значению name, как в оригинальной задаче.
Кобанчег, у тебя в последней строчке 'e',3,6 вместо 'е',3,5 - намеренно или опечатка?
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020883
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сравним скорость, или подождем PL/SQL варианта?
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020884
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Кобанчег, у тебя в последней строчке 'e',3,6 вместо 'е',3,5 - намеренно или опечатка?
Опечатка скорее. Предполагалось исходные данные оставить как есть.
Но "опечатка" была использована ранее для тестирования.
НеофитSQL
Код: plsql
1.
from cte e, p

Я вижу джойн, а ты?
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020885
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Сравним скорость, или подождем PL/SQL варианта?
Если хотя бы отдалённо понимать принцип работы, то абсолютно очевидно что PL/SQL здесь несомненный лидер.
SQL-но и безджойно было "just for fun".

PS. Икстендер публиковал PL/SQL подход.
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020890
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и по приколу линейный проход.
Но это не спортивно ибо xmlquery (которым вообще-то можно реализовать какие-угодно джойны)
+ ограничение на длину конкатенации + предполагается что входные имена не содержат запятых.
Код: 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.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
SQL> with ranges (name, range_start, range_end) as
  2  (
  3  select 'a', 0, 7 from dual
  4  union all select 'b', 2, 4 from dual
  5  union all select 'c', 1, 3 from dual
  6  union all select 'd', 4, 5 from dual
  7  union all select 'e', 3, 5 from dual
  8  --
  9  union all select 'x', 3, 3.1 from dual
 10  union all select 'y', 3.5, 3.7 from dual
 11  union all select 'z', 3.9, 5.1 from dual
 12  union all select 'a', 8, 9 from dual
 13  union all select 'a', 8, 9.9 from dual
 14  )
 15  select --+ no_xml_query_rewrite
 16    x, s str, xmlcast(xmlquery('max(tokenize(.,","))' passing(t.s) returning content) as varchar2(4000)) name
 17    from
 18  (
 19    select x, max(s) keep (dense_rank last order by name) s
 20      from
 21    (
 22      select *
 23        from (select x, name, sum(sum(r)) over (partition by name order by x) r
 24                from ranges unpivot(x for r in(range_start as '1', range_end as '-1'))
 25               group by x, name)
 26      model
 27      dimension by(row_number() over (order by x, name) i)
 28      measures(x, name, r, cast('' as varchar2(4000)) s)
 29      rules
 30      (
 31        s[i] = case
 32                 when r[cv()] = 0 then replace(s[cv()-1], name[cv()] || ',')
 33                 else
 34                   case
 35                     when nvl(instr(s[cv()-1], name[cv()] || ','), 0) > 0 then s[cv()-1]
 36                     else s[cv()-1] || name[cv()] || ','
 37                   end
 38               end
 39      )
 40    )
 41    group by x
 42  ) t
 43  order by 1;

         X STR        NAME
---------- ---------- ----------
         0 a,         a
         1 a,c,       c
         2 a,c,b,     c
         3 a,b,e,x,   x
       3.1 a,b,e,     e
       3.5 a,b,e,y,   y
       3.7 a,b,e,     e
       3.9 a,b,e,z,   z
         4 a,e,z,d,   z
         5 a,z,       z
       5.1 a,         a
         7
         8 a,         a
         9 a,         a
       9.9

15 rows selected.

...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40020919
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кобанчег

НеофитSQL
Код: plsql
1.
from cte e, p

Я вижу джойн, а ты?


Я его написал :)

Понадеялся что джойн по константе исполняется эффективно.

Не всякий "from a, b" стоит циклов, бывают бесплатные или дешёвые. Например, "from a,b where b.rowid=x" ничего не должен стоить.

Больше беспокоит многопроходность.
В худшем случае мой алгоритм дает О(n*n) шагов и 3n памяти.

В лучшем, O(n).
...
Рейтинг: 0 / 0
Пятничная задача: Красное и черное
    #40021505
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сделал пару быстрых проверок на таблице из 10К строк.
Самое простое решение с подчиненным циклом оказалось довольно медленным, несмотря на наличие индексов:

Код: 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.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
-- без агрегации групп, формат вывода как у xtender
SQL> select x, (select max(color) from test_ranges where range_start <= x and range_end > x) from
  2  (select range_start x from test_ranges union select range_end from test_ranges) order by x;

20000 rows selected.

Elapsed: 00:02:59.52

Execution Plan
----------------------------------------------------------

| Id  | Operation                         | Name             | Rows  | Bytes |TempSpc| Cost (%CPU)|

---------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT                  |                  |  1999K|    24M|     | 28455   (2)|
|   1 |  SORT AGGREGATE                   |                  |     1 |    49 |     |            |
|   2 |   TABLE ACCESS BY INDEX ROWID     | TEST_RANGES      |  2500 |   119K|     |   981   (1)|
|   3 |    BITMAP CONVERSION TO ROWIDS    |                  |       |       |     |            |
|   4 |     BITMAP AND                    |                  |       |       |     |            |
|   5 |      BITMAP CONVERSION FROM ROWIDS|                  |       |       |     |            |
|   6 |       SORT ORDER BY               |                  |       |       | 800K|            |
|   7 |        INDEX RANGE SCAN           | TEST_RANGES_IDX1 |       |       |     |    43   (0)|
|   8 |      BITMAP CONVERSION FROM ROWIDS|                  |       |       |     |            |
|   9 |       SORT ORDER BY               |                  |       |       | 800K|            |
|  10 |        INDEX RANGE SCAN           | TEST_RANGES_IDX2 |       |       |     |    44   (0)|
|  11 |  SORT ORDER BY                    |                  |  1999K|    24M|  38M| 28455   (2)|
|  12 |   VIEW                            |                  |  1999K|    24M|     | 18871   (1)|
|  13 |    SORT UNIQUE                    |                  |  1999K|    41M|  53M| 18871  (51)|
|  14 |     UNION-ALL                     |                  |       |       |     |            |
|  15 |      TABLE ACCESS FULL            | TEST_RANGES      |   999K|    20M|     |  2753   (1)|
|  16 |      TABLE ACCESS FULL            | TEST_RANGES      |   999K|    20M|     |  2754   (1)|

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
   45481209  consistent gets
          0  physical reads
          0  redo size
     653151  bytes sent via SQL*Net to client
      15023  bytes received via SQL*Net from client
       1335  SQL*Net roundtrips to/from client
      40002  sorts (memory)
          0  sorts (disk)
      20000  rows processed



Рекурсивное решение:
Код: 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.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
SQL> with p (r,c,a,b) as (
  2            select color, color, range_start, range_end from test_ranges
  3  union all select color, null, null, range_start       from test_ranges
  4  union all select color, null, range_end, null         from test_ranges
  5  ),
  6  cte (n, clr, x, y) as (
  7  select max(color)+1, null, min(range_start), max(range_end) from test_ranges union all
  8  select n-1, c, nvl2(a,greatest(x,a),x), nvl2(b,least(y,b),y)
  9    from cte e, p
 10   where n > 1 and r=n-1 and clr is null and x < y
 11  )
 12  select * from cte where x < y and clr is not null order by x;

31 rows selected.

Elapsed: 00:00:46.25

Execution Plan
----------------------------------------------------------

| Id  | Operation                                  | Name        | Rows  | Bytes | Cost (%CPU)|

-----------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT                           |             |     4 |   208 | 13793   (1)|
|   1 |  SORT ORDER BY                             |             |     4 |   208 | 13793   (1)|
|   2 |   VIEW                                     |             |     4 |   208 | 13792   (1)|
|   3 |    UNION ALL (RECURSIVE WITH) BREADTH FIRST|             |       | |            |
|   4 |     SORT AGGREGATE                         |             |     1 |    49 |            |
|   5 |      TABLE ACCESS FULL                     | TEST_RANGES |   999K|    46M|  2754   (1)|
|   6 |     HASH JOIN                              |             |     3 |   312 | 11038   (1)|
|   7 |      RECURSIVE WITH PUMP                   |             |       | |            |
|   8 |      VIEW                                  |             |  2999K|   148M|  8262   (1)|
|   9 |       UNION-ALL                            |             |       | |            |
|  10 |        TABLE ACCESS FULL                   | TEST_RANGES |   999K|    46M|  2754   (1)|
|  11 |        TABLE ACCESS FULL                   | TEST_RANGES |   999K|    25M|  2753   (1)|
|  12 |        TABLE ACCESS FULL                   | TEST_RANGES |   999K|    25M|  2754   (1)|

--------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
          2  recursive calls
      60582  db block gets
    2389761  consistent gets
          0  physical reads
          0  redo size
       2341  bytes sent via SQL*Net to client
        382  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
       8049  sorts (memory)
          0  sorts (disk)
         31  rows processed



Как заполнялась тест таблица:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SQL> insert into test_ranges select level, dbms_random.value(0,10), null from dual connect by level <= 10000;
10000 rows inserted
Executed in 0,156 seconds

SQL> update test_ranges set range_end=dbms_random.value(range_start,10);
10000 rows updated
Executed in 0,578 seconds

SQL> alter index test_ranges_idx1 rebuild online;

Index altered.

Elapsed: 00:00:00.09
SQL> alter index test_ranges_idx2 rebuild online;

Index altered.

Elapsed: 00:00:00.11
...
Рейтинг: 0 / 0
25 сообщений из 176, страница 7 из 8
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Пятничная задача: Красное и черное
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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