powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Помогите с запросиком (аналитическая функция???)
59 сообщений из 59, показаны все 3 страниц
Помогите с запросиком (аналитическая функция???)
    #39727584
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Постановка задачи:
Имеем табличку
Код: 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   1 id, 1 idx, TO_DATE('01.01.2000 00:00:00', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   2 id, 6 idx, TO_DATE('01.01.2000 00:00:01', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   3 id, 7 idx, TO_DATE('01.01.2000 00:00:02', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   4 id, 7 idx, TO_DATE('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   5 id, 8 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   6 id, 7 idx, TO_DATE('01.01.2000 00:00:05', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   7 id, 7 idx, TO_DATE('01.01.2000 00:00:06', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL

    SELECT   8 id, 0 idx, TO_DATE('01.01.2000 00:00:07', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL

    SELECT   9 id, 1 idx, TO_DATE('01.01.2000 00:00:08', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL

    SELECT  10 id, 0 idx, TO_DATE('01.01.2000 00:00:09', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL

    SELECT  11 id, 1 idx, TO_DATE('01.01.2000 00:00:10', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  12 id, 2 idx, TO_DATE('01.01.2000 00:00:11', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  13 id, 5 idx, TO_DATE('01.01.2000 00:00:12', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  14 id, 6 idx, TO_DATE('01.01.2000 00:00:13', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  15 id, 6 idx, TO_DATE('01.01.2000 00:00:14', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  16 id, 7 idx, TO_DATE('01.01.2000 00:00:15', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  17 id, 7 idx, TO_DATE('01.01.2000 00:00:16', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL
)


Нужно построить запрос, который возвращает id всех строки таблички, за исключением "повторов", т.е. для "повторов" только первую строку вернуть нужно.
И запрос должен быть вида:
Код: 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.
WITH t AS ( SELECT   1 id, 1 idx, TO_DATE('01.01.2000 00:00:00', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   2 id, 6 idx, TO_DATE('01.01.2000 00:00:01', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   3 id, 7 idx, TO_DATE('01.01.2000 00:00:02', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   4 id, 7 idx, TO_DATE('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   5 id, 8 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   6 id, 7 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   7 id, 7 idx, TO_DATE('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
        
            SELECT   8 id, 0 idx, TO_DATE('01.01.2000 00:00:07', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
        
            SELECT   9 id, 1 idx, TO_DATE('01.01.2000 00:00:08', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
        
            SELECT  10 id, 0 idx, TO_DATE('01.01.2000 00:00:09', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
        
            SELECT  11 id, 1 idx, TO_DATE('01.01.2000 00:00:10', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  12 id, 2 idx, TO_DATE('01.01.2000 00:00:11', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  13 id, 5 idx, TO_DATE('01.01.2000 00:00:12', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  14 id, 6 idx, TO_DATE('01.01.2000 00:00:13', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  15 id, 6 idx, TO_DATE('01.01.2000 00:00:14', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  16 id, 7 idx, TO_DATE('01.01.2000 00:00:15', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  17 id, 7 idx, TO_DATE('01.01.2000 00:00:16', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL
)
SELECT  id
FROM   (SELECT  id
            ,   (CASE WHEN <Условие>
                      THEN 1
                      ELSE 0
                 END) cond
        FROM    t
        )
WHERE  cond = 1


т.е. <Условие> нужно прописать.

Уточнения:
"Первая" - это та, у которой d наименьшее, при равных d - c минимальным id (id уникальны).
"Повторами" считаются записи внутри календарных суток с одинаковым idx , однако, если встретилась строка с FLAG =1, то "забываем" про повтор.

Поясню на примере для idx=7:
строку с id=4 нужно вывести в отчет, а строки с id in (4,6,7) - нет, это "повторы".
Кроме того, строку с id=16 тоже нужно вывести в отчет, т.к. между строками 4 и 16 имеются строки с FLAD=1 (id=8, 10).
Строку 17 снова не выводим - это "повтор" 16.

Сам пробовал через
Код: plsql
1.
COUNT(1) OVER(PARTITION BY TRUNC(d), idx ORDER BY d ASC, id) = 1


т.е. для строки смотрим - по группе с таким же idx берем только первую, однако мозг сломал, как мне FLAG=1 тут учесть...

По идее, нужно группы еще разбить по моменту появления FLAG=1, но что-то не врублюсь как.

Помогите, пожалуйста, если не сложно.

PS структура данных и запрос - не мои, приходится "вписываться"
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39727587
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuHесли встретилась строка с FLAG =1, то "забываем" про повтор.STFF start_of_group. Например
Код: plsql
1.
sum(flag) over (partition by trunc(d), idx order by d asc, id) as group_no


KOT MATPOCKuHСам пробовал через
Код: plsql
1.
COUNT(1) OVER(PARTITION BY TRUNC(d), idx ORDER BY d ASC, id)

Код: plsql
1.
row_number() over (partition by trunc(d), idx, group_no order by d asc, id)
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39727588
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic,
не отразил, как это "засунуть" в запрос вместо "Условие" ?
Ведь так же не напишешь
Код: plsql
1.
row_number() over (partition by trunc(d), idx, sum(flag) over (partition by trunc(d), idx order by d asc, id) order by d asc, id)=1
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39727590
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuHкак это "засунуть" в запрос вместо "Условие" ?Никак. Нужны inline view.
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39727591
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
idx бывают 0 .. 255
может это как-то поможет?
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39727592
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuHможет это как-то поможет?Спроси у астрологов.
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39727600
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic,

Логично, фигню спросил )))

FLAG=0 обычно с idx=0
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39727601
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
т.е. если бы в группу по idx можно было кроме записей с idx=idx еще и добавить с idx=0 ...
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39727625
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuHPS структура данных и запрос - не мои, приходится "вписываться"Subquery с вытекающей гибкостью, но тормознутостью.
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39727705
SkilledJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KOT MATPOCKuH,

Код: 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.
with t as (
    SELECT   1 id, 1 idx, TO_DATE('01.01.2000 00:00:00', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   2 id, 6 idx, TO_DATE('01.01.2000 00:00:01', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   3 id, 7 idx, TO_DATE('01.01.2000 00:00:06', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   4 id, 7 idx, TO_DATE('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   5 id, 8 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   6 id, 7 idx, TO_DATE('01.01.2000 00:00:05', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   7 id, 7 idx, TO_DATE('01.01.2000 00:00:02', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   8 id, 0 idx, TO_DATE('01.01.2000 00:00:07', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
    SELECT   9 id, 1 idx, TO_DATE('01.01.2000 00:00:08', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  10 id, 0 idx, TO_DATE('01.01.2000 00:00:09', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
    SELECT  11 id, 1 idx, TO_DATE('01.01.2000 00:00:10', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  12 id, 2 idx, TO_DATE('01.01.2000 00:00:11', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  13 id, 5 idx, TO_DATE('01.01.2000 00:00:12', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  14 id, 6 idx, TO_DATE('01.01.2000 00:00:13', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  15 id, 6 idx, TO_DATE('01.01.2000 00:00:14', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  16 id, 7 idx, TO_DATE('01.01.2000 00:00:15', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  17 id, 7 idx, TO_DATE('01.01.2000 00:00:16', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL
),
t_flag_gr as (
                select  t.*,
                        sum(case flag when 1 then 1 else 0 end) over (partition by trunc(d) order by d, id) flag_group_no
                from t
),
t_sog as (
            select t_flag_gr.*,
                   lag(idx) over(partition by trunc(d) order by idx, d, id),
                   case when lag(idx) over (partition by trunc(d) order by idx, d, id) = idx and
                             lag(flag_group_no) over (partition by trunc(d) order by idx, d, id) = flag_group_no
                        then 0 else 1 end sog
            from t_flag_gr
),
t_gr as (
            select  t_sog.*,
                    sum(sog) over (partition by trunc(d) order by idx, d, id) group_no
            from t_sog
)
select *
from t
where id in (select first_value(id) over (partition by trunc(d), idx, group_no order by d , id) from t_gr)
order by d, id
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39727711
SkilledJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Надо было сначала Elic-a почитать

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
t_flag_gr as (
                select  t.*,
                        sum(case flag when 1 then 1 else 0 end) over (partition by trunc(d) order by d, id) flag_group_no
                from t
)
select * from (select t_flag_gr.*, row_number() over (partition by trunc(d), idx, flag_group_no order by d asc, id) rn from t_flag_gr)
where rn = 1
order by d, id
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39727736
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SkilledJuniorНадо было сначала Elic-a почитать
Код: plsql
1.
sum(case flag when 1 then 1 else 0 end)

Недочитал.
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39727803
SkilledJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ElicНедочитал.
Насколько я понял автора топика, триггерная только единица и могут быть значения отличные от 0 и 1.
KOT MATPOCKuHidx бывают 0 .. 255
может это как-то поможет?
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39727804
SkilledJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пардон невнимательно прочитал
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39727902
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Как решить с помощью start_of_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.
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.
64.
65.
66.
67.
with t as ( select   1 id, 1 idx, to_date('01.01.2000 00:00:00', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
            select   2 id, 6 idx, to_date('01.01.2000 00:00:01', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
            select   3 id, 7 idx, to_date('01.01.2000 00:00:02', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
            select   4 id, 7 idx, to_date('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
            select   5 id, 8 idx, to_date('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
            select   6 id, 7 idx, to_date('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
            select   7 id, 7 idx, to_date('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all        
            select   8 id, 0 idx, to_date('01.01.2000 00:00:07', 'dd.mm.yyyy hh24:mi:ss') d, 1 flag from dual union all        
            select   9 id, 1 idx, to_date('01.01.2000 00:00:08', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all        
            select  10 id, 0 idx, to_date('01.01.2000 00:00:09', 'dd.mm.yyyy hh24:mi:ss') d, 1 flag from dual union all        
            select  11 id, 1 idx, to_date('01.01.2000 00:00:10', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
            select  12 id, 2 idx, to_date('01.01.2000 00:00:11', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
            select  13 id, 5 idx, to_date('01.01.2000 00:00:12', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
            select  14 id, 6 idx, to_date('01.01.2000 00:00:13', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
            select  15 id, 6 idx, to_date('01.01.2000 00:00:14', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
            select  16 id, 7 idx, to_date('01.01.2000 00:00:15', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
            select  17 id, 7 idx, to_date('01.01.2000 00:00:16', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual
          )
,t2 as (select t.*
              ,row_number() over (partition by trunc(d), idx order by d, id) rn
              ,sum(t.flag) over (partition by trunc(d) order by d, id)       summ
              ,lag(t.id) over (partition by trunc(d), idx order by d, id)    lagid
          from t
       )
,t3 as (select a.*
              ,a.summ - nvl(b.summ, 0) summ2
          from t2 a left join t2 b on a.lagid = b.id       
       )
select id
  from (select id
              ,(case 
                 when 
                   case
                     when rn = 1 then 1 
                     else 
                       case 
                         when flag = 1 then 1
                         else 
                           case 
                             when summ2 > 0 then 1
                             else 0
                          end
                       end
                   end = 1 then 1
                 else 0
               end) as cond
          from t3
        )
 where cond = 1
 order by id

        ID
----------
         1
         2
         3
         5
         8
         9
        10
        11
        12
        13
        14
        16

 12 rows selected
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39727908
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rushchelКак решить с помощью start_of_group? У меня только такой вариант вышел.row_number() нужно считать с учётом групп на основе flag.
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728012
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuH,

Мне в голову только такое пришло, хотя пн. утро - я еще сплю Может что и не дочитал в условии
Код: 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.
WITH t AS ( SELECT   1 id, 1 idx, TO_DATE('01.01.2000 00:00:00', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   2 id, 6 idx, TO_DATE('01.01.2000 00:00:01', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   3 id, 7 idx, TO_DATE('01.01.2000 00:00:02', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   4 id, 7 idx, TO_DATE('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   5 id, 8 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   6 id, 7 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   7 id, 7 idx, TO_DATE('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
        
            SELECT   8 id, 0 idx, TO_DATE('01.01.2000 00:00:07', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
        
            SELECT   9 id, 1 idx, TO_DATE('01.01.2000 00:00:08', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
        
            SELECT  10 id, 0 idx, TO_DATE('01.01.2000 00:00:09', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
        
            SELECT  11 id, 1 idx, TO_DATE('01.01.2000 00:00:10', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  12 id, 2 idx, TO_DATE('01.01.2000 00:00:11', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  13 id, 5 idx, TO_DATE('01.01.2000 00:00:12', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  14 id, 6 idx, TO_DATE('01.01.2000 00:00:13', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  15 id, 6 idx, TO_DATE('01.01.2000 00:00:14', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  16 id, 7 idx, TO_DATE('01.01.2000 00:00:15', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  17 id, 7 idx, TO_DATE('01.01.2000 00:00:16', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL
)
SELECT  id
FROM   (SELECT  id
            ,   (CASE WHEN (min(id) over (partition by idx, trunc(d) order by d, id) = id) or flag = 1
                      THEN 1
                      ELSE 0
                 END) cond
        FROM    t
        )
WHERE  cond = 1
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728015
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximaXXLне дочитал
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728021
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Почему непременно аналитикой-то?
pattern matching жеж прям-таки просится.
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728028
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousПочему непременно аналитикой-то?
pattern matching жеж прям-таки просится.

А ну ка сбацай =)
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728030
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicMaximaXXLне дочитал

Я так и знал, вот выпил кофе и получилось вот такое:
Код: 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.
WITH t AS ( SELECT   1 id, 1 idx, TO_DATE('01.01.2000 00:00:00', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   2 id, 6 idx, TO_DATE('01.01.2000 00:00:01', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   3 id, 7 idx, TO_DATE('01.01.2000 00:00:02', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   4 id, 7 idx, TO_DATE('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   5 id, 8 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   6 id, 7 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   7 id, 7 idx, TO_DATE('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
        
            SELECT   8 id, 0 idx, TO_DATE('01.01.2000 00:00:07', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
        
            SELECT   9 id, 1 idx, TO_DATE('01.01.2000 00:00:08', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
        
            SELECT  10 id, 0 idx, TO_DATE('01.01.2000 00:00:09', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
        
            SELECT  11 id, 1 idx, TO_DATE('01.01.2000 00:00:10', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  12 id, 2 idx, TO_DATE('01.01.2000 00:00:11', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  13 id, 5 idx, TO_DATE('01.01.2000 00:00:12', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  14 id, 6 idx, TO_DATE('01.01.2000 00:00:13', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  15 id, 6 idx, TO_DATE('01.01.2000 00:00:14', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  16 id, 7 idx, TO_DATE('01.01.2000 00:00:15', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  17 id, 7 idx, TO_DATE('01.01.2000 00:00:16', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL
)
, t1 as (select id, idx+sum(flag) over (order by id)*1000 idx, d from t)

SELECT  id
FROM   (SELECT  id
            ,   (CASE WHEN min(id) over (partition by idx, trunc(d) order by d, id) = id
                      THEN 1
                      ELSE 0
                 END) cond
        FROM    t1
        )
WHERE  cond = 1



умножал на 1000, потому что так нагляднее и это при условии что автор утверждает что
KOT MATPOCKuHidx бывают 0 .. 255
может это как-то поможет?
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728033
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximaXXL,

Код: plsql
1.
, t1 as (select id, idx+sum(flag) over (partition by trunc(d) order by d, id)*1000 idx, d from t)



вот это забыл, просто пример был только за 1 дату
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728038
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximaXXL,

Фигня в том, что не могу я в запросе кроме как <Условие> что-то вставлять.
Ограничение на <Условие> только одно: 2к байт.

Если интересно объясню:
1) запрос этот делаю не я, он такой зашит в систему, править не могу.
<Условие> - подставляется динамоэскуэлем из некой таблички - в нее могу вносить записи с нужным критерием.
Собственно это и является самым жестким критерием поставленной здесь задачки

2) Данные - падают из другой системы, это события некого оборудования, которые приходят в БД (исходную) разными путями.
Время - это время поступления их в ту БД, поэтому, в таблице много дублей, которые, по сути, и хочется отсечь.
Объем - в день несколько лямов строк.


Пока я проблему решил простым способом - создал функцию, которую и вызываю в <Условие>. Производительность оставляет желать лучшего...
Однако хотелось бы ...
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728043
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuH,

А можете создать view и на нее натравить свой запрос? Или это тоже прибито гвоздями?
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728046
SkilledJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
"Все уже украдено до нас"
Elic
Код: plsql
1.
sum(flag) over (partition by trunc(d), idx order by d asc, id) as group_no


Код: plsql
1.
row_number() over (partition by trunc(d), idx, group_no order by d asc, id)


Другие варианты получаются из разряда 100 верст не крюк))
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728053
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuH,

Ну можно упороться и подсунуть такое условие (уж не знаю на сколько будет быстрее)

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
SELECT  id
FROM   (SELECT  id
            ,   (CASE WHEN exists (select 1 
                                     from (select id, 
                                                  row_number() over (partition by idx, trunc(d), group_no order by d, id) rn 
                                            from (select id, idx, sum(flag) over (partition by trunc(d) order by d, id) group_no, d from t) t3) t4 
                                    where t4.id = t.id and t4.rn = 1)
                      THEN 1
                      ELSE 0
                 END) cond
        FROM    t
        )
WHERE  cond = 1
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728058
SkilledJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: 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.
with t as (
    SELECT   1 id, 1 idx, TO_DATE('01.01.2000 00:00:00', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   2 id, 6 idx, TO_DATE('01.01.2000 00:00:01', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   3 id, 7 idx, TO_DATE('01.01.2000 00:00:06', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   4 id, 7 idx, TO_DATE('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   5 id, 8 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   6 id, 7 idx, TO_DATE('01.01.2000 00:00:05', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   7 id, 7 idx, TO_DATE('01.01.2000 00:00:02', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   8 id, 0 idx, TO_DATE('01.01.2000 00:00:07', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
    SELECT   9 id, 1 idx, TO_DATE('01.01.2000 00:00:08', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  10 id, 0 idx, TO_DATE('01.01.2000 00:00:09', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
    SELECT  11 id, 1 idx, TO_DATE('01.01.2000 00:00:10', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  12 id, 2 idx, TO_DATE('01.01.2000 00:00:11', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  13 id, 5 idx, TO_DATE('01.01.2000 00:00:12', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  14 id, 6 idx, TO_DATE('01.01.2000 00:00:13', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  15 id, 6 idx, TO_DATE('01.01.2000 00:00:14', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  16 id, 7 idx, TO_DATE('01.01.2000 00:00:15', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  17 id, 7 idx, TO_DATE('01.01.2000 00:00:16', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL
)
SELECT  id
FROM   (SELECT  id
               ,(CASE WHEN id =
(
select b.id from (
               select id, row_number() over (partition by trunc(d), idx, flag_group_no order by d asc, id) rn
               from (
                      select a.id, a.idx, a.d, sum(a.flag) over (partition by trunc(a.d) order by a.d, a.id) flag_group_no
                      from t a
                      where trunc(a.d) = trunc(t.d)
                    )
               ) b
where rn = 1 and t.id = b.id
)
                      THEN 1
                      ELSE 0
                 END) cond
        FROM    t
        )
WHERE  cond = 1
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728061
SkilledJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Думал жестко зашито
Код: plsql
1.
CASE WHEN id =

если не жестко то CASE WHEN EXISTS
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728066
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если у каждой записи будет FLAG = 1, то результат должен вернуть все id?
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728071
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KOT MATPOCKuH, а можешь расписать логику для idx = 1 и опубликовать какой должен быть результат на тестовых данных?
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728082
SkilledJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rushchel,

Все уже разжевано вдоль и поперек, для idx=1, id = 1,9,11, логика такая же как и для idx=7
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728125
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кажись разжевал.
Код: 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.
WITH t AS ( SELECT   1 id, 1 idx, TO_DATE('01.01.2000 00:00:00', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   2 id, 6 idx, TO_DATE('01.01.2000 00:00:01', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   3 id, 7 idx, TO_DATE('01.01.2000 00:00:02', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   4 id, 7 idx, TO_DATE('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   5 id, 8 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   6 id, 7 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   7 id, 7 idx, TO_DATE('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   8 id, 0 idx, TO_DATE('01.01.2000 00:00:07', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
            SELECT   9 id, 1 idx, TO_DATE('01.01.2000 00:00:08', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  10 id, 0 idx, TO_DATE('01.01.2000 00:00:09', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
            SELECT  11 id, 1 idx, TO_DATE('01.01.2000 00:00:10', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  12 id, 2 idx, TO_DATE('01.01.2000 00:00:11', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  13 id, 5 idx, TO_DATE('01.01.2000 00:00:12', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  14 id, 6 idx, TO_DATE('01.01.2000 00:00:13', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  15 id, 6 idx, TO_DATE('01.01.2000 00:00:14', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  16 id, 7 idx, TO_DATE('01.01.2000 00:00:15', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  17 id, 7 idx, TO_DATE('01.01.2000 00:00:16', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL
)
SELECT  id
FROM   (SELECT  id
            ,   (case when 1 = (select c.rn 
                                  from (select row_number() over (partition by trunc(b.d), b.idx, b.start_of_group order by b.d, b.id) rn, b.*
                                          from (select sum(a.flag) over (partition by trunc(a.d) order by a.d, a.id) start_of_group, a.*
                                                  from t a
                                               ) b
                                       ) c 
                                where c.id = t.id)
                      THEN 1
                      ELSE 0
                 END) cond
        FROM    t
        )
WHERE  cond = 1

        ID
----------
         1
         2
         3
         5
         8
         9
        10
        11
        12
        13
        14
        16

 12 rows selected
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728131
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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.
WITH t AS ( SELECT   1 id, 1 idx, TO_DATE('01.01.2000 00:00:00', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   2 id, 6 idx, TO_DATE('01.01.2000 00:00:01', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   3 id, 7 idx, TO_DATE('01.01.2000 00:00:02', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   4 id, 7 idx, TO_DATE('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   5 id, 8 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   6 id, 7 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   7 id, 7 idx, TO_DATE('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT   8 id, 0 idx, TO_DATE('01.01.2000 00:00:07', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
            SELECT   9 id, 1 idx, TO_DATE('01.01.2000 00:00:08', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  10 id, 0 idx, TO_DATE('01.01.2000 00:00:09', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
            SELECT  11 id, 1 idx, TO_DATE('01.01.2000 00:00:10', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  12 id, 2 idx, TO_DATE('01.01.2000 00:00:11', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  13 id, 5 idx, TO_DATE('01.01.2000 00:00:12', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  14 id, 6 idx, TO_DATE('01.01.2000 00:00:13', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  15 id, 6 idx, TO_DATE('01.01.2000 00:00:14', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  16 id, 7 idx, TO_DATE('01.01.2000 00:00:15', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
            SELECT  17 id, 7 idx, TO_DATE('01.01.2000 00:00:16', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL
),
grp as (
        select  id,
                idx,
                sum(flag) over(order by id) grp
          from  t
       )
select  min(id)
  from  grp
  group by grp,
           idx
  order by 1
/

             MIN(ID)
--------------------
                   1
                   2
                   3
                   5
                   8
                   9
                  10
                  11
                  12
                  13
                  14
                  16

12 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728139
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY,

автор"Повторами" считаются записи внутри календарных суток с одинаковым idx ...

.....
stax
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728157
SkilledJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY,

И сортировка в группах сначала по дате d потом по id, для
Код: plsql
1.
2.
3.
4.
with t as (
    SELECT   3 id, 7 idx, TO_DATE('01.01.2000 00:00:06', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   7 id, 7 idx, TO_DATE('01.01.2000 00:00:02', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL
)


Результат должен быть 7.
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728168
SkilledJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY,

Твой вариант должен выглядеть как то так:
Код: 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.
with t as (
    SELECT   1 id, 1 idx, TO_DATE('01.01.2000 00:00:00', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   2 id, 6 idx, TO_DATE('01.01.2000 00:00:01', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   3 id, 7 idx, TO_DATE('01.01.2000 00:00:06', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   4 id, 7 idx, TO_DATE('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   5 id, 8 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   6 id, 7 idx, TO_DATE('01.01.2000 00:00:05', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   7 id, 7 idx, TO_DATE('01.01.2000 00:00:02', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   8 id, 0 idx, TO_DATE('01.01.2000 00:00:07', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
    SELECT   9 id, 1 idx, TO_DATE('01.01.2000 00:00:08', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  10 id, 0 idx, TO_DATE('01.01.2000 00:00:09', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
    SELECT  11 id, 1 idx, TO_DATE('01.01.2000 00:00:10', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  12 id, 2 idx, TO_DATE('01.01.2000 00:00:11', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  13 id, 5 idx, TO_DATE('01.01.2000 00:00:12', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  14 id, 6 idx, TO_DATE('01.01.2000 00:00:13', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  15 id, 6 idx, TO_DATE('01.01.2000 00:00:14', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  16 id, 7 idx, TO_DATE('01.01.2000 00:00:15', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  17 id, 7 idx, TO_DATE('01.01.2000 00:00:16', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL
),
grp as (
        select  id,
                idx,
                d,
                sum(flag) over (partition by trunc(d) order by d, id) grp
          from  t
       )
select  min(id) keep (dense_rank first order by d, id)
  from  grp
  group by trunc(d),
           grp,
           idx
  order by 1
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728206
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SkilledJuniorSY,

Твой вариант должен выглядеть как то так:


A, не заметил "Повторами считаются записи внутри календарных суток с одинаковым idx". И решение должнo выглядеть совсем не так.
Все что нужно это добавить trunc(d) в group by:

Код: 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.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
SQL> WITH t AS ( SELECT   1 id, 1 idx, TO_DATE('01.01.2000 00:00:00', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
  2              SELECT   2 id, 6 idx, TO_DATE('01.01.2000 00:00:01', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
  3              SELECT   3 id, 7 idx, TO_DATE('01.01.2000 00:00:02', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
  4              SELECT   4 id, 7 idx, TO_DATE('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
  5              SELECT   5 id, 8 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
  6              SELECT   6 id, 7 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
  7              SELECT   7 id, 7 idx, TO_DATE('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
  8              SELECT   8 id, 0 idx, TO_DATE('01.01.2000 00:00:07', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
  9              SELECT   9 id, 1 idx, TO_DATE('01.01.2000 00:00:08', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
 10              SELECT  10 id, 0 idx, TO_DATE('01.01.2000 00:00:09', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
 11              SELECT  11 id, 1 idx, TO_DATE('01.01.2000 00:00:10', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
 12              SELECT  12 id, 2 idx, TO_DATE('01.01.2000 00:00:11', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
 13              SELECT  13 id, 5 idx, TO_DATE('01.01.2000 00:00:12', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
 14              SELECT  14 id, 6 idx, TO_DATE('01.01.2000 00:00:13', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
 15              SELECT  15 id, 6 idx, TO_DATE('01.01.2000 00:00:14', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
 16              SELECT  16 id, 7 idx, TO_DATE('01.01.2000 00:00:15', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
 17              SELECT  17 id, 7 idx, TO_DATE('01.01.2000 00:00:16', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL
 18  ),
 19  grp as (
 20          select  id,
 21                  idx,
 22                  d,
 23                  sum(flag) over(order by id) grp
 24            from  t
 25         )
 26  select  min(id) keep (dense_rank first order by d) id
 27    from  grp
 28    group by grp,
 29             idx,
 30             trunc(d)
 31    order by 1
 32  /

                  ID
--------------------
                   1
                   2
                   3
                   5
                   8
                   9
                  10
                  11
                  12
                  13
                  14
                  16

12 rows selected.

SQL> WITH t AS ( SELECT   1 id, 1 idx, TO_DATE('01.01.2000 00:00:00', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
  2              SELECT   2 id, 6 idx, TO_DATE('01.01.2000 00:00:01', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
  3              SELECT   3 id, 7 idx, TO_DATE('01.01.2000 00:00:02', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
  4              SELECT   4 id, 7 idx, TO_DATE('02.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
  5              SELECT   5 id, 8 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
  6              SELECT   6 id, 7 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
  7              SELECT   7 id, 7 idx, TO_DATE('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
  8              SELECT   8 id, 0 idx, TO_DATE('01.01.2000 00:00:07', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
  9              SELECT   9 id, 1 idx, TO_DATE('01.01.2000 00:00:08', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
 10              SELECT  10 id, 0 idx, TO_DATE('01.01.2000 00:00:09', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
 11              SELECT  11 id, 1 idx, TO_DATE('01.01.2000 00:00:10', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
 12              SELECT  12 id, 2 idx, TO_DATE('01.01.2000 00:00:11', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
 13              SELECT  13 id, 5 idx, TO_DATE('01.01.2000 00:00:12', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
 14              SELECT  14 id, 6 idx, TO_DATE('01.01.2000 00:00:13', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
 15              SELECT  15 id, 6 idx, TO_DATE('01.01.2000 00:00:14', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
 16              SELECT  16 id, 7 idx, TO_DATE('01.01.2000 00:00:15', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
 17              SELECT  17 id, 7 idx, TO_DATE('01.01.2000 00:00:16', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL
 18  ),
 19  grp as (
 20          select  id,
 21                  idx,
 22                  d,
 23                  sum(flag) over(order by id) grp
 24            from  t
 25         )
 26  select  min(id) keep (dense_rank first order by d) id
 27    from  grp
 28    group by grp,
 29             idx,
 30             trunc(d)
 31    order by 1
 32  /

                  ID
--------------------
                   1
                   2
                   3
                   4
                   5
                   8
                   9
                  10
                  11
                  12
                  13
                  14
                  16

13 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728207
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, нe ясно как трактовать "если встретилась строка с FLAG=1, то "забываем" про повтор." Забываем вообще или для данного IDX? Я посчитал вообще (исходя из результатов последней выборки от rushchel). Если для данного IDX, то добавить partition by idx в sum.

SY.
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728222
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYКстати, нe ясно как трактовать "если встретилась строка с FLAG=1, то "забываем" про повтор." Забываем вообще или для данного IDX?


Вообще, для всех idx.

Единственное решение поставленной задачи предложил rushchel

В любом случае, получается минимум 3 "соединения таблицы самой с собой", а т.к. она не маленькая, то и производительность страдает...
Ограничение выборки окнами аналитики не особо помогает (в предложенных решениях).
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728224
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Даже не самой с собой, а просто 3 просмотра таблицы
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728245
SkilledJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KOT MATPOCKuHЕдинственное решение поставленной задачи предложил rushchel
А я думал решение предложил Elic еще во втором сообщении 21723276 , не?
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728257
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuHДаже не самой с собой, а просто 3 просмотра таблицы

И где-же ты насчитал три просмотра?

Код: 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.
SQL> explain plan for
  2  with grp as (
  3          select  id,
  4                  idx,
  5                  d,
  6                  sum(flag) over(order by id) grp
  7            from  tbl
  8         )
  9  select  min(id) keep (dense_rank first order by d) id
 10    from  grp
 11    group by grp,
 12             idx,
 13             trunc(d)
 14    order by 1
 15  /

Explained.

SQL> select * from table(dbms_xplan.display)
  2  /

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2378169033

------------------------------------------------------------------------------
| Id  | Operation             | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |      |    17 |   629 |     6  (50)| 00:00:01 |
|   1 |  SORT ORDER BY        |      |    17 |   629 |     6  (50)| 00:00:01 |
|   2 |   SORT GROUP BY       |      |    17 |   629 |     6  (50)| 00:00:01 |
|   3 |    VIEW               |      |    17 |   629 |     4  (25)| 00:00:01 |
|   4 |     WINDOW SORT       |      |    17 |   272 |     4  (25)| 00:00:01 |
|   5 |      TABLE ACCESS FULL| TBL  |    17 |   272 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------

12 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728258
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuHЕдинственное решение поставленной задачи предложил rushchel


21724487

SY.
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728279
SkilledJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY,

У него тяжелый случай, условие можно поставить только в CASE WHEN, сам запрос зашит в приложении и поменять он его не может.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
create table t as (
    SELECT   1 id, 1 idx, TO_DATE('01.01.2000 00:00:00', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   2 id, 6 idx, TO_DATE('01.01.2000 00:00:01', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   3 id, 7 idx, TO_DATE('01.01.2000 00:00:06', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   4 id, 7 idx, TO_DATE('02.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   5 id, 8 idx, TO_DATE('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   6 id, 7 idx, TO_DATE('01.01.2000 00:00:05', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   7 id, 7 idx, TO_DATE('01.01.2000 00:00:02', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT   8 id, 0 idx, TO_DATE('01.01.2000 00:00:07', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
    SELECT   9 id, 1 idx, TO_DATE('01.01.2000 00:00:08', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  10 id, 0 idx, TO_DATE('01.01.2000 00:00:09', 'dd.mm.yyyy hh24:mi:ss') d, 1 FLAG FROM DUAL UNION ALL
    SELECT  11 id, 1 idx, TO_DATE('01.01.2000 00:00:10', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  12 id, 2 idx, TO_DATE('01.01.2000 00:00:11', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  13 id, 5 idx, TO_DATE('01.01.2000 00:00:12', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  14 id, 6 idx, TO_DATE('01.01.2000 00:00:13', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  15 id, 6 idx, TO_DATE('01.01.2000 00:00:14', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  16 id, 7 idx, TO_DATE('01.01.2000 00:00:15', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL UNION ALL
    SELECT  17 id, 7 idx, TO_DATE('01.01.2000 00:00:16', 'dd.mm.yyyy hh24:mi:ss') d, 0 FLAG FROM DUAL
)


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT  id
FROM   (SELECT  id
            ,   (CASE WHEN EXISTS
                          (select 1 from (select  min(id) keep (dense_rank first order by d) id
                                            from  (select id, idx, d, sum(flag) over(order by id) grp from t)
                                            group by grp, idx, trunc(d)) m
                                    where t.id = m.id)

                      THEN 1
                      ELSE 0
                 END) cond
        FROM t
        )
WHERE  cond = 1
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728326
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728344
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Решил собрать опубликованные решения на текущее время
Код: 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.
create table tab_base as 
select * from (
    select   1 id, 1 idx, to_date('01.01.2000 00:00:00', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
    select   2 id, 6 idx, to_date('01.01.2000 00:00:01', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
    select   3 id, 7 idx, to_date('01.01.2000 00:00:02', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
    select   4 id, 7 idx, to_date('01.01.2000 00:00:03', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
    select   5 id, 8 idx, to_date('01.01.2000 00:00:04', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
    select   6 id, 7 idx, to_date('01.01.2000 00:00:05', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
    select   7 id, 7 idx, to_date('01.01.2000 00:00:06', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
    select   8 id, 0 idx, to_date('01.01.2000 00:00:07', 'dd.mm.yyyy hh24:mi:ss') d, 1 flag from dual union all
    select   9 id, 1 idx, to_date('01.01.2000 00:00:08', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
    select  10 id, 0 idx, to_date('01.01.2000 00:00:09', 'dd.mm.yyyy hh24:mi:ss') d, 1 flag from dual union all
    select  11 id, 1 idx, to_date('01.01.2000 00:00:10', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
    select  12 id, 2 idx, to_date('01.01.2000 00:00:11', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
    select  13 id, 5 idx, to_date('01.01.2000 00:00:12', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
    select  14 id, 6 idx, to_date('01.01.2000 00:00:13', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
    select  15 id, 6 idx, to_date('01.01.2000 00:00:14', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
    select  16 id, 7 idx, to_date('01.01.2000 00:00:15', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual union all
    select  17 id, 7 idx, to_date('01.01.2000 00:00:16', 'dd.mm.yyyy hh24:mi:ss') d, 0 flag from dual
);
create table tab_big as
select rownum as id
      ,trunc(256 * dbms_random.value) as idx
      ,to_date('01.01.2000','dd.mm.yyyy') + trunc(86400 * dbms_random.value)/(24 * 60 * 60) as d
      ,trunc(17 / 15 * dbms_random.value) as flag
  from dual connect by level <= 2000000;

Код: 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.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
explain plan for --1
--with t as (select * from tab_base)
with t as (select * from tab_big)
select id
  from (select id
              ,(case when exists (select 1 
                                    from (select id
                                                ,row_number() over (partition by idx, trunc(d), group_no order by d, id) rn 
                                            from (select id, idx, sum(flag) over (partition by trunc(d) order by d, id) group_no, d from t) t3
                                         ) t4 
                                   where t4.id = t.id 
                                     and t4.rn = 1)
                  then 1
                  else 0
                end) cond
          from t
       )
 where cond = 1;
select * from table(dbms_xplan.display); 
----------------------------------------------------------------------
| Id  | Operation                 | Name     | Rows  | Bytes | Cost  |
----------------------------------------------------------------------
|   0 | SELECT STATEMENT          |          |    17 |    51 |    36 |
|   1 |  FILTER                   |          |       |       |       |
|   2 |   TABLE ACCESS FULL       | TAB_BASE |    17 |    51 |     2 |
|   3 |   VIEW                    |          |     1 |    26 |     4 |
|   4 |    WINDOW SORT PUSHED RANK|          |    17 |   646 |     4 |
|   5 |     VIEW                  |          |    17 |   646 |     3 |
|   6 |      WINDOW SORT          |          |    17 |   272 |     3 |
|   7 |       TABLE ACCESS FULL   | TAB_BASE |    17 |   272 |     2 |
----------------------------------------------------------------------

---------------------------------------------------------------------
| Id  | Operation                 | Name    | Rows  | Bytes | Cost  |
---------------------------------------------------------------------
|   0 | SELECT STATEMENT          |         |  2000K|    11M|    33G|
|   1 |  FILTER                   |         |       |       |       |
|   2 |   TABLE ACCESS FULL       | TAB_BIG |  2000K|    11M|   327 |
|   3 |   VIEW                    |         |     1 |    26 | 16674 |
|   4 |    WINDOW SORT PUSHED RANK|         |  2000K|    74M| 16674 |
|   5 |     VIEW                  |         |  2000K|    74M|  6366 |
|   6 |      WINDOW SORT          |         |  2000K|    36M|  6366 |
|   7 |       TABLE ACCESS FULL   | TAB_BIG |  2000K|    36M|   285 |
---------------------------------------------------------------------
 
explain plan for --2
--with t as (select * from tab_base)
with t as (select * from tab_big)
select id
  from (select id
              ,(case when id = (select b.id 
                                  from (select id, row_number() over (partition by trunc(d), idx, flag_group_no order by d asc, id) rn
                                          from (select a.id, a.idx, a.d, sum(a.flag) over (partition by trunc(a.d) order by a.d, a.id) flag_group_no
                                                  from t a
                                                 where trunc(a.d) = trunc(t.d)
                                               )
                                       ) b
                                 where rn = 1 
                                   and t.id = b.id
                               )
                  then 1
                  else 0
                end) cond
          from t
       )
 where cond = 1;
select * from table(dbms_xplan.display);
----------------------------------------------------------------------
| Id  | Operation                 | Name     | Rows  | Bytes | Cost  |
----------------------------------------------------------------------
|   0 | SELECT STATEMENT          |          |     1 |    11 |    36 |
|   1 |  FILTER                   |          |       |       |       |
|   2 |   TABLE ACCESS FULL       | TAB_BASE |    17 |   187 |     2 |
|   3 |   VIEW                    |          |     1 |    26 |     4 |
|   4 |    WINDOW SORT PUSHED RANK|          |     1 |    38 |     4 |
|   5 |     VIEW                  |          |     1 |    38 |     3 |
|   6 |      WINDOW SORT          |          |     1 |    16 |     3 |
|   7 |       TABLE ACCESS FULL   | TAB_BASE |     1 |    16 |     2 |
----------------------------------------------------------------------
 
---------------------------------------------------------------------
| Id  | Operation                 | Name    | Rows  | Bytes | Cost  |
---------------------------------------------------------------------
|   0 | SELECT STATEMENT          |         |     1 |    14 |  1184M|
|   1 |  FILTER                   |         |       |       |       |
|   2 |   TABLE ACCESS FULL       | TAB_BIG |  2000K|    26M|   331 |
|   3 |   VIEW                    |         |     1 |    26 |   593 |
|   4 |    WINDOW SORT PUSHED RANK|         | 20000 |   761K|   593 |
|   5 |     VIEW                  |         | 20000 |   761K|   488 |
|   6 |      WINDOW SORT          |         | 20000 |   371K|   488 |
|   7 |       TABLE ACCESS FULL   | TAB_BIG | 20000 |   371K|   486 |
---------------------------------------------------------------------
 
explain plan for --3
--with t as (select * from tab_base)
with t as (select * from tab_big)
select id
  from (select id
              ,(case when 1 = (select c.rn 
                                 from (select row_number() over (partition by trunc(b.d), b.idx, b.start_of_group order by b.d, b.id) rn, b.*
                                         from (select sum(a.flag) over (partition by trunc(a.d) order by a.d, a.id) start_of_group, a.*
                                                 from t a
                                              ) b
                                      ) c 
                                where c.id = t.id)
                  then 1
                  else 0
                end) cond
          from t
        )
 where cond = 1;
select * from table(dbms_xplan.display);
-------------------------------------------------------------------
| Id  | Operation              | Name     | Rows  | Bytes | Cost  |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT       |          |     1 |     3 |    36 |
|   1 |  FILTER                |          |       |       |       |
|   2 |   TABLE ACCESS FULL    | TAB_BASE |    17 |    51 |     2 |
|   3 |   VIEW                 |          |    17 |   442 |     4 |
|   4 |    WINDOW SORT         |          |    17 |   646 |     4 |
|   5 |     VIEW               |          |    17 |   646 |     3 |
|   6 |      WINDOW SORT       |          |    17 |   272 |     3 |
|   7 |       TABLE ACCESS FULL| TAB_BASE |    17 |   272 |     2 |
-------------------------------------------------------------------
 
------------------------------------------------------------------
| Id  | Operation              | Name    | Rows  | Bytes | Cost  |
------------------------------------------------------------------
|   0 | SELECT STATEMENT       |         |     1 |     6 |    33G|
|   1 |  FILTER                |         |       |       |       |
|   2 |   TABLE ACCESS FULL    | TAB_BIG |  2000K|    11M|   331 |
|   3 |   VIEW                 |         |  2000K|    49M| 16674 |
|   4 |    WINDOW SORT         |         |  2000K|    74M| 16674 |
|   5 |     VIEW               |         |  2000K|    74M|  6366 |
|   6 |      WINDOW SORT       |         |  2000K|    36M|  6366 |
|   7 |       TABLE ACCESS FULL| TAB_BIG |  2000K|    36M|   285 |
------------------------------------------------------------------
 
explain plan for --4
--with t as (select * from tab_base)
with t as (select * from tab_big)
select id
  from (select id
              ,(case when exists (select 1 
                                    from (select min(id) keep (dense_rank first order by d) id
                                            from (select id
                                                        ,idx
                                                        ,d
                                                        ,sum(flag) over(order by id) grp
                                                    from t
                                                 )
                                            group by grp, idx, trunc(d)
                                         ) m
                                   where m.id = t.id)
                  then 1
                  else 0
                end) cond
          from t
        )
 where cond = 1;
select * from table(dbms_xplan.display);
-------------------------------------------------------------------
| Id  | Operation              | Name     | Rows  | Bytes | Cost  |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT       |          |    17 |    51 |    36 |
|   1 |  FILTER                |          |       |       |       |
|   2 |   TABLE ACCESS FULL    | TAB_BASE |    17 |    51 |     2 |
|   3 |   FILTER               |          |       |       |       |
|   4 |    SORT GROUP BY       |          |     1 |    37 |     4 |
|   5 |     VIEW               |          |    17 |   629 |     3 |
|   6 |      WINDOW SORT       |          |    17 |   272 |     3 |
|   7 |       TABLE ACCESS FULL| TAB_BASE |    17 |   272 |     2 |
-------------------------------------------------------------------

------------------------------------------------------------------
| Id  | Operation              | Name    | Rows  | Bytes | Cost  |
------------------------------------------------------------------
|   0 | SELECT STATEMENT       |         |  2000K|    11M|    12G|
|   1 |  FILTER                |         |       |       |       |
|   2 |   TABLE ACCESS FULL    | TAB_BIG |  2000K|    11M|   327 |
|   3 |   FILTER               |         |       |       |       |
|   4 |    SORT GROUP BY       |         | 20000 |   742K|  6491 |
|   5 |     VIEW               |         |  2000K|    72M|  6366 |
|   6 |      WINDOW SORT       |         |  2000K|    36M|  6366 |
|   7 |       TABLE ACCESS FULL| TAB_BIG |  2000K|    36M|   285 |
------------------------------------------------------------------
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728345
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rushchelРешил собрать опубликованные решенияЗачем?
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728353
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ElicrushchelРешил собрать опубликованные решенияЗачем?Сравнить хотел. А Что?
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728379
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rushchelСравнить хотел. А Что?А смысл?
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728385
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ElicrushchelСравнить хотел. А Что?А смысл?Зачем?
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728398
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rushchelElicпропущено...
А смысл?Зачем?Раз смысла не видишь, то зачем бисеришь?
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728407
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Elicrushchelпропущено...
Зачем?Раз смысла не видишь, то зачем бисеришь?Я тебя не понимаю. Хочешь что-то сказать - пиши прямо.
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728648
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SkilledJuniorSY,

У него тяжелый случай, условие можно поставить только в CASE WHEN, сам запрос зашит в приложении и поменять он его не может.


И что? Как ты думаешь столько раз оракл выполнит subquery M и сколько раз он будет в ней искать?

SY.
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728650
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYКак ты думаешь столько раз оракл выполнит subquery в EXISTS correlated subquery
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728669
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicSYКак ты думаешь столько раз оракл выполнит subquery в EXISTS correlated subquery

M не correlated, ну а вообще-то можно:

Код: 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.
SQL> explain plan for
  2  SELECT  id
  3  FROM   (SELECT  id
  4              ,   (CASE WHEN EXISTS
  5                            (with m as (select /*+ materialize */ min(id) keep (dense_rank first order by d) id
  6                                              from  (select id, idx, d, sum(flag) over(order by id) grp from tbl)
  7                                              group by grp, idx, trunc(d))
  8                             select 1 from m where t.id = m.id)
  9                        THEN 1
 10                        ELSE 0
 11                   END) cond
 12          FROM tbl t
 13          )
 14  WHERE  cond = 1
 15  /

Explained.

SQL> select * from table(dbms_xplan.display)
  2  /

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2529294160

-------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                 | Name                        | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                          |                             |    17 |    51 |    63  (27)| 00:00:01 |
|*  1 |  FILTER                                   |                             |       |       |            |          |
|   2 |   TABLE ACCESS FULL                       | TBL                         |    17 |    51 |     3   (0)| 00:00:01 |
|   3 |   TEMP TABLE TRANSFORMATION               |                             |       |       |            |          |
|   4 |    LOAD AS SELECT (CURSOR DURATION MEMORY)| SYS_TEMP_0FD9D67AC_C67C599D |       |       |            |          |
|   5 |     SORT GROUP BY                         |                             |    17 |   629 |     5  (40)| 00:00:01 |
|   6 |      VIEW                                 |                             |    17 |   629 |     4  (25)| 00:00:01 |
|   7 |       WINDOW SORT                         |                             |    17 |   272 |     4  (25)| 00:00:01 |
|   8 |        TABLE ACCESS FULL                  | TBL                         |    17 |   272 |     3   (0)| 00:00:01 |
|*  9 |    VIEW                                   |                             |    17 |   221 |     2   (0)| 00:00:01 |
|  10 |     TABLE ACCESS FULL                     | SYS_TEMP_0FD9D67AC_C67C599D |    17 |   221 |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(CASE  WHEN  EXISTS (SELECT 0 FROM  (SELECT /*+ CACHE ("T1") */ "C0" "ID" FROM
              "SYS"."SYS_TEMP_0FD9D67AC_C67C599D" "T1") "M" WHERE "M"."ID"=:B1) THEN 1 ELSE 0 END =1)
   9 - filter("M"."ID"=:B1)

24 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728678
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Или:

Код: 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.
SQL> explain plan for
  2  SELECT  id
  3  FROM   (SELECT  id
  4              ,   (CASE WHEN EXISTS
  5                            (select /*+ CACHE(M) */ 1 from (select  min(id) keep (dense_rank first order by d) id,row_number() ove
r(order by grp) rn
  6                                              from  (select id, idx, d, sum(flag) over(order by id) grp from tbl)
  7                                              group by grp, idx, trunc(d)) m
  8                                      where t.id = m.id)
  9                        THEN 1
 10                        ELSE 0
 11                   END) cond
 12          FROM tbl t
 13          )
 14  WHERE  cond = 1
 15  /

Explained.

SQL> select * from table(dbms_xplan.display)
  2  /

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2110295973

-------------------------------------------------------------------------------
| Id  | Operation              | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |      |    17 |    51 |    46  (37)| 00:00:01 |
|*  1 |  FILTER                |      |       |       |            |          |
|   2 |   TABLE ACCESS FULL    | TBL  |    17 |    51 |     3   (0)| 00:00:01 |
|*  3 |   FILTER               |      |       |       |            |          |
|   4 |    SORT GROUP BY       |      |     1 |    37 |     5  (40)| 00:00:01 |
|   5 |     VIEW               |      |    17 |   629 |     4  (25)| 00:00:01 |
|   6 |      WINDOW SORT       |      |    17 |   272 |     4  (25)| 00:00:01 |
|   7 |       TABLE ACCESS FULL| TBL  |    17 |   272 |     3   (0)| 00:00:01 |
-------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(CASE  WHEN  EXISTS (SELECT /*+ CACHE
              ("from$_subquery$_003") */ 0 FROM  (SELECT "ID" "ID","IDX" "IDX","D"
              "D",SUM("FLAG") OVER ( ORDER BY "ID" RANGE  BETWEEN  UNBOUNDED
              PRECEDING  AND  CURRENT ROW ) "GRP" FROM "TBL" "TBL")
              "from$_subquery$_003" GROUP BY "GRP","IDX",TRUNC(INTERNAL_FUNCTION("D"))
               HAVING MIN("ID") KEEP (DENSE_RANK FIRST  ORDER BY "D")=:B1) THEN 1
              ELSE 0 END =1)
   3 - filter(MIN("ID") KEEP (DENSE_RANK FIRST  ORDER BY "D")=:B1)

26 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39728912
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuHПока я проблему решил простым способом - создал функцию, которую и вызываю в <Условие>. Производительность оставляет желать лучшего...
Однако хотелось бы ...
Если функцию можно - то, быть может, можно и индекс?
Если да, то есть разные варианты.

Ну и не забываем про классику...
Изложите <Условие> в виде
Код: plsql
1.
2.
3.
4.
5.
                      1=1 then 0 end) cond 
         from t where 1=0
        union all 
<Тут любой устраивающий вариант, возвращающий "id, 1">
union all select 0, (case when 1=0


и наслаждайтесь.
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39729024
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousНу и не забываем про классику...Инъекция...
...
Рейтинг: 0 / 0
Помогите с запросиком (аналитическая функция???)
    #39729152
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elicandrey_anonymousНу и не забываем про классику...Инъекция...
ессно :)
...
Рейтинг: 0 / 0
59 сообщений из 59, показаны все 3 страниц
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Помогите с запросиком (аналитическая функция???)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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