powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Можно сделать через аналитические функции или только через именнованные подзапросы?
18 сообщений из 18, страница 1 из 1
Можно сделать через аналитические функции или только через именнованные подзапросы?
    #40016790
mod
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть выборка select rec.rec_id, rec.data_op from tmp_tbl rec
where rec.data_op between data1 and data2
Задача - добавить в выводимые поля min_rec_id и max_rec_id
, где min_rec_id - id минимальной записи в периоде или, если в периоде нет записей, то максимальной записи до периода, а max_rec_id, максимальной записи в периоде или максимальной до периода, если в периоде нет записей.
...
Рейтинг: 0 / 0
Можно сделать через аналитические функции или только через именнованные подзапросы?
    #40016791
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вы бы исходные данные и ожидаемый результат представили, что-ли...
...
Рейтинг: 0 / 0
Можно сделать через аналитические функции или только через именнованные подзапросы?
    #40016795
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mod,

union all

аналитические функции тебя не спасут - ты хочешь выдеть мир за пределами стены фильтрации данных.
Так что, либо union all, либо чья-то гарантия , что в пределах фильтра ты увидишь всё, что тебе нужно.
...
Рейтинг: 0 / 0
Можно сделать через аналитические функции или только через именнованные подзапросы?
    #40016798
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous,

да и так понятно - "остаток на начало периода фильтрации" он хочет получать.
...
Рейтинг: 0 / 0
Можно сделать через аналитические функции или только через именнованные подзапросы?
    #40016799
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby
да и так понятно - "остаток на начало периода фильтрации" он хочет получать.

Это не повод истирать пальцы об клавиатуру, выдумывая набор за ТС :)
...
Рейтинг: 0 / 0
Можно сделать через аналитические функции или только через именнованные подзапросы?
    #40016800
mod
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rec_id data_op
1 01.01.2020
2 02.01.2020
3 13.03.2020

data_1 = 05.02.2020, data_2 = 12.02.2020

Результат:
2 2 null null (min_rec_id, max_rec_id, rec_id, data_op)

data_1 = 31.12.2019, data_2 = 05.02.2020
Результат:
1 2 1 01.01.2020
1 2 2 02.01.2020
Как именнованными понятно, если даты диапазона увести в dual. Можно ли как-то окнами?
...
Рейтинг: 0 / 0
Можно сделать через аналитические функции или только через именнованные подзапросы?
    #40016803
mod
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby,

Ну значит да, пусть будут именнованные подзапросы. Спасибо! Просто аналитическими редко приходится пользоваться. Уточнил - вдруг чего да упускаю
...
Рейтинг: 0 / 0
Можно сделать через аналитические функции или только через именнованные подзапросы?
    #40016805
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mod
вдруг чего да упускаю

Вообще упускаете, но тут можно на performance penalties налететь если данных много и нельзя сделать разумного предположения о максимальном размере перерыва в датах.
...
Рейтинг: 0 / 0
Можно сделать через аналитические функции или только через именнованные подзапросы?
    #40016815
mod
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous, потому м спросил - простое решение понятно, но оно, безусловно по скорости может быть не фонтан. Перерывы могут быть и большие.
...
Рейтинг: 0 / 0
Можно сделать через аналитические функции или только через именнованные подзапросы?
    #40016821
graycode
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mod,
Если в периоде нет записей, то ваш запрос не вернет ничего, поэтому вероятно union all, только одной синтетической записи, а не тех которые вы добавили.

Для оформления кода используйте пожалуйста тег src.

Думаю, если вы пример исходных данных набросаете в with, то ваш вопрос отпадет сам собой.
...
Рейтинг: 0 / 0
Можно сделать через аналитические функции или только через именнованные подзапросы?
    #40016823
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mod
rec_id data_op
1 01.01.2020
2 02.01.2020
3 13.03.2020

data_1 = 05.02.2020, data_2 = 12.02.2020

Результат:
2 2 null null (min_rec_id, max_rec_id, rec_id, data_op)

data_1 = 31.12.2019, data_2 = 05.02.2020
Результат:
1 2 1 01.01.2020
1 2 2 02.01.2020
Как именнованными понятно, если даты диапазона увести в dual. Можно ли как-то окнами?

еще раз: окна не умеют работать вне диапазона фильтрации.

Поэтому, если точно внутри одного sql-запроса, сначала формируете такой набор, на котором окна смогут работать правильно,
и только потом, поверх этого набора - окна.
...
Рейтинг: 0 / 0
Можно сделать через аналитические функции или только через именнованные подзапросы?
    #40016838
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mod,
Код: 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.
SQL> 
  1  with t (rec_id, data_op) as (
  2  select 1,to_date('01.01.2020') from dual union all
  3  select 2,to_date('02.01.2020') from dual union all
  4  select 3,to_date('13.03.2020') from dual
  5  )
  6  select t.*,min(rec_id) over() min_id,max(rec_id) over() max_id
  7  from t
  8  where data_op between :d1 and :d2
  9  UNION ALL
 10  select null,null,(select max(rec_id) from t where data_op<:d1),(select min(rec_id) from t where data_op>:d2)
 11* from dual where not exists (select 1 from t where data_op between :d1 and :d2)
SQL> /

    REC_ID DATA_OP        MIN_ID     MAX_ID
---------- ---------- ---------- ----------
                               2
SQL> exec :d1:='05.02.2020';

PL/SQL procedure successfully completed.

SQL> exec :d2:='12.02.2020';

PL/SQL procedure successfully completed.
SQL> /

    REC_ID DATA_OP        MIN_ID     MAX_ID
---------- ---------- ---------- ----------
                               2          3

SQL> exec :d1:='31.12.2019';

PL/SQL procedure successfully completed.

SQL> exec :d2:='05.02.2020';

PL/SQL procedure successfully completed.

SQL> /

    REC_ID DATA_OP        MIN_ID     MAX_ID
---------- ---------- ---------- ----------
         1 01.01.2020          1          2
         2 02.01.2020          1          2

SQL>



....
stax
...
Рейтинг: 0 / 0
Можно сделать через аналитические функции или только через именнованные подзапросы?
    #40016840
graycode
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax,

Если условие задачи прочитать немного внимательнее, то результат неверный и скалярные подзапросы лишние.
...
Рейтинг: 0 / 0
Можно сделать через аналитические функции или только через именнованные подзапросы?
    #40016842
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax,

Код: plsql
1.
(select max(rec_id) from t where data_op<:d1)



Неофит пока еще заблокирован, и вряд ли сможет от себя лично выдать гарантии на правильную работу такого запроса.
...
Рейтинг: 0 / 0
Можно сделать через аналитические функции или только через именнованные подзапросы?
    #40016863
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
graycode
Stax,

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


считал 2 2 очепяткой

Код: 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.
SQL> exec :d1:='05.02.2020';

PL/SQL procedure successfully completed.

SQL> exec :d2:='12.02.2020';

PL/SQL procedure successfully completed.

SQL> l
  1  with t (rec_id, data_op) as (
  2  select 1,to_date('01.01.2020') from dual union all
  3  select 2,to_date('02.01.2020') from dual union all
  4  select 3,to_date('13.03.2020') from dual
  5  )
  6  select min(rec_id) over() min_id,max(rec_id) over() max_id ,t.*
  7  from t
  8  where data_op between :d1 and :d2
  9  UNION ALL
 10  select (select max(rec_id) from t where data_op<:d1),(select min(rec_id) from t where data_op>:d2), null,null
 11* from dual where not exists (select 1 from t where data_op between :d1 and :d2)
SQL> /

    MIN_ID     MAX_ID     REC_ID DATA_OP
---------- ---------- ---------- ----------
         2          3

SQL>



Ваш вариант?

ps
у меня тож есть и другие варианты решения

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

Код: plsql
1.
(select max(rec_id) from t where data_op<:d1)



Неофит пока еще заблокирован, и вряд ли сможет от себя лично выдать гарантии на правильную работу такого запроса.


гарантии насчет :d1?
мне просто лень было всюду прописывать to_date

.....
stax
...
Рейтинг: 0 / 0
Можно сделать через аналитические функции или только через именнованные подзапросы?
    #40016894
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax,
я подразумевал вот что:
обычно, предполагаемая логика в этой, изложенной в стиле "максимальной записи до периода" задаче, такая:

ищется нечто, слева максимально близкое по дате к заказанному диапазону поиска + набор данных в диапазоне поиска.
Смысл такого поиска в том, что история "объекта" может начинаться слева до начала диапазона поиска, и нужно отыскать
"истинное состояние объекта" на начало анализируемого диапазона времени.

Из полученного вычислением выводится нечто, относящееся к концу заказанного периода поиска.

В этом смысле, в терминах условного rec_id, понимается такой rec_id, который относится к самому близкому слева моменту времени.
В варианте (select max(rec_id) from t where data_op<:d1) для обеспечения такого условия необходима гарантия
монотонного возрастания rec_id со временем.
Иначе запрос вернет данные, не соответствующие развернуто выраженному намерению.

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

Stax,
я подразумевал вот что:
....

да, так более логично, я принял условие буквально

если нужно не мах/min то поменять на keep и first/last

Код: 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.
SQL> print :d1 :d2

D1
--------------------------------
31.12.2019


D2
--------------------------------
12.02.2020


  1  with t (rec_id, data_op) as (
  2  select 5,to_date('20.12.2019') from dual union all
  3  select 4,to_date('01.01.2020') from dual union all
  4  select 1,to_date('02.01.2020') from dual union all
  5  select 3,to_date('03.01.2020') from dual union all
  6  select 9,to_date('13.02.2020') from dual union all
  7  select 8,to_date('15.02.2020') from dual
  8  )
  9  select
 10   first_value(rec_id) over(order by data_op ASC ) min_id
 11  ,first_value(rec_id) over(order by data_op DESC) max_id --last_value
 12  ,t.*
 13  from t
 14  where data_op between :d1 and :d2
 15  UNION ALL
 16  select (select * from (select rec_id from t where data_op<:d1 order by data_op desc) where rownum=1) --keep
 17       ,(select * from (select rec_id from t where data_op>:d1 order by data_op ) where rownum=1)
 18       ,null,null
 19  from dual where not exists (select 1 from t where data_op between :d1 and :d2)
 20* order by 4
SQL> /

    MIN_ID     MAX_ID     REC_ID DATA_OP
---------- ---------- ---------- ----------
         4          3          4 01.01.2020
         4          3          1 02.01.2020
         4          3          3 03.01.2020

SQL>



.....
stax
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Можно сделать через аналитические функции или только через именнованные подзапросы?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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