Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Выбор последних событий для каждого Id / 6 сообщений из 6, страница 1 из 1
22.08.2018, 10:10
    #39691509
Synoptic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор последних событий для каждого Id
Коллеги, есть ли более изящное решение, чем подобное?

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
create table sql_test (stateDate date, Id numeric(19), state varchar2(255), type varchar(255), nexttdate date);

insert into sql_test values(to_date('01.08.2018','dd.mm.yyyy'), 1, 'Created',  'FULL',  to_date('02.08.2018','dd.mm.yyyy'));
insert into sql_test values(to_date('02.08.2018','dd.mm.yyyy'), 1, 'Prepared', 'FULL',  to_date('03.08.2018','dd.mm.yyyy'));
insert into sql_test values(to_date('03.08.2018','dd.mm.yyyy'), 1, 'Packed',   'FULL',  to_date('04.08.2018','dd.mm.yyyy'));
insert into sql_test values(to_date('04.08.2018','dd.mm.yyyy'), 1, 'Shipped',  'FULL',  to_date('05.08.2018','dd.mm.yyyy'));
insert into sql_test values(to_date('05.08.2018','dd.mm.yyyy'), 1, 'Closed',   'FULL',  null);

insert into sql_test values(to_date('01.08.2018','dd.mm.yyyy'), 2, 'Created',   null,  to_date('02.08.2018','dd.mm.yyyy'));
insert into sql_test values(to_date('02.08.2018','dd.mm.yyyy'), 2, 'Prepared',  null,  to_date('03.08.2018','dd.mm.yyyy'));
insert into sql_test values(to_date('03.08.2018','dd.mm.yyyy'), 2, 'Packed',    null,  to_date('04.08.2018','dd.mm.yyyy'));
insert into sql_test values(to_date('04.08.2018','dd.mm.yyyy'), 2, 'Shipped',   null,  to_date('10.08.2018','dd.mm.yyyy'));

insert into sql_test values(to_date('01.08.2018','dd.mm.yyyy'), 3, 'Created',  'FULL',  to_date('02.08.2018','dd.mm.yyyy'));
insert into sql_test values(to_date('02.08.2018','dd.mm.yyyy'), 3, 'Prepared', 'FULL',  to_date('03.08.2018','dd.mm.yyyy'));
insert into sql_test values(to_date('03.08.2018','dd.mm.yyyy'), 3, 'Packed',   'FULL',  to_date('02.08.2018','dd.mm.yyyy'));
insert into sql_test values(to_date('04.08.2018','dd.mm.yyyy'), 3, 'Shipped',  'FULL',  to_date('04.08.2018','dd.mm.yyyy'));
insert into sql_test values(to_date('05.08.2018','dd.mm.yyyy'), 3, 'Shipped',  'FULL',  to_date('11.08.2018','dd.mm.yyyy'));

commit;



Ну и запрос:
Код: plsql
1.
2.
with tmp(statedate, id) as (select max(statedate) , id  from sql_test group by id)
select * from sql_test where (statedate, id) in (select * from tmp) ;



STATEDATEIDSTATETYPENEXTTDATE05.08.20181ClosedFULL 04.08.20182Shipped10.08.201805.08.20183ShippedFULL11.08.2018
...
Рейтинг: 0 / 0
22.08.2018, 10:27
    #39691525
Dshedoo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор последних событий для каждого Id
Synoptic,

Код: 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.
with tmp(stateDate, Id, state, type, nexttdate) as ( 
          select to_date('01.08.2018','dd.mm.yyyy'), 1, 'Created',  'FULL',  to_date('02.08.2018','dd.mm.yyyy') from dual
union all select to_date('02.08.2018','dd.mm.yyyy'), 1, 'Prepared', 'FULL',  to_date('03.08.2018','dd.mm.yyyy') from dual
union all select to_date('03.08.2018','dd.mm.yyyy'), 1, 'Packed',   'FULL',  to_date('04.08.2018','dd.mm.yyyy') from dual
union all select to_date('04.08.2018','dd.mm.yyyy'), 1, 'Shipped',  'FULL',  to_date('05.08.2018','dd.mm.yyyy') from dual
union all select to_date('05.08.2018','dd.mm.yyyy'), 1, 'Closed',   'FULL',  null from dual

union all select to_date('01.08.2018','dd.mm.yyyy'), 2, 'Created',   null,  to_date('02.08.2018','dd.mm.yyyy')from dual
union all select to_date('02.08.2018','dd.mm.yyyy'), 2, 'Prepared',  null,  to_date('03.08.2018','dd.mm.yyyy')from dual
union all select to_date('03.08.2018','dd.mm.yyyy'), 2, 'Packed',    null,  to_date('04.08.2018','dd.mm.yyyy')from dual
union all select to_date('04.08.2018','dd.mm.yyyy'), 2, 'Shipped',   null,  to_date('10.08.2018','dd.mm.yyyy')from dual

union all select to_date('01.08.2018','dd.mm.yyyy'), 3, 'Created',  'FULL',  to_date('02.08.2018','dd.mm.yyyy') from dual
union all select to_date('02.08.2018','dd.mm.yyyy'), 3, 'Prepared', 'FULL',  to_date('03.08.2018','dd.mm.yyyy') from dual
union all select to_date('03.08.2018','dd.mm.yyyy'), 3, 'Packed',   'FULL',  to_date('02.08.2018','dd.mm.yyyy') from dual
union all select to_date('04.08.2018','dd.mm.yyyy'), 3, 'Shipped',  'FULL',  to_date('04.08.2018','dd.mm.yyyy') from dual
union all select to_date('05.08.2018','dd.mm.yyyy'), 3, 'Shipped',  'FULL',  to_date('11.08.2018','dd.mm.yyyy') from dual)

, w as (select max(statedate) KEEP (dense_rank last order by statedate) as w1
, max(id) KEEP (dense_rank last order by statedate) as w2
, max(state) KEEP (dense_rank last order by statedate) as w3
, max(type ) KEEP (dense_rank last order by statedate) as w4
, max(nexttdate ) KEEP (dense_rank last order by statedate) as w5 from tmp
group by id)

, e (statedate, id) as (select max(statedate) , id  from tmp group by id)
, r as (select * from tmp where (statedate, id) in (select * from e))

select * from w full join r on w1 = stateDate and w2 = Id and w3 = state and lnnvl(w4 != type) and lnnvl(w5 != nexttdate)
...
Рейтинг: 0 / 0
22.08.2018, 10:28
    #39691528
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор последних событий для каждого Id
1)
Код: plsql
1.
select * from (select … over … as rnk, t.* from t) where rnk = 1

2) RTFM FIRST/LAST aggregate functions
...
Рейтинг: 0 / 0
22.08.2018, 10:34
    #39691541
Synoptic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор последних событий для каждого Id
Ясно.
Теже байты только сбоку :)
...
Рейтинг: 0 / 0
22.08.2018, 10:58
    #39691563
Щукина Анна
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор последних событий для каждого Id
Synoptic,

order by row_number() over(partition by id order by statedate desc)
fetch first 1 row with ties
...
Рейтинг: 0 / 0
22.08.2018, 14:37
    #39691785
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор последних событий для каждого Id
Твое решение через KEEP (так-же как наброски в остальных ответах) не эквиваленто исходному. Исходное вернет все строки с max(statedate) для id а твое только одну и причем недетерминированную - слепленую из max значений всех отдельных полей строк с max(statedate) для id. Эквивалентно через RANK/DENSE_RANK.

SY.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Выбор последних событий для каждого Id / 6 сообщений из 6, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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