#sql #optimization #partition
#sql #оптимизация #перегородка
Вопрос:
В процессе оптимизации запросов я добрался до следующего SQL-запроса:
select s.*
from
(
select id, DATA, update_dt, inspection_dt, check_dt
RANK OVER()
(PARTITION by ID
ORDER BY update_dt DESC, DATA) rank
FROM TABLE
where update_dt < inspection_dt or update_dt < check_dt
) r
where r.rank = 1
Запрос возвращает ДАННЫЕ, соответствующие последнему check_dt.
Однако то, что я хочу получить, это:
1. ДАННЫЕ, соответствующие последнему check_dt
2. ДАННЫЕ, соответствующие последнему inspection_dt.
Одно из тривиальных решений — просто напишите два отдельных запроса с единственным условием where — один для inspection_dt и один для check_dt. Однако таким образом теряется первоначальное намерение — сократить время выполнения.
Наблюдая за исходными данными, я заметил способ его реализации — дата проверки всегда позже даты проверки; зная, что я мог бы просто извлечь запись с рангом = 1, и она даст мне ДАННЫЕ, соответствующие последнему CHECK_DT, а запись с наибольшим рангом будет соответствовать ПРОВЕРКЕ. Однако, боюсь, данные не всегда будут согласованными, поэтому я искал более абстрактное решение.
Ответ №1:
Как насчет этого?
select s.*
from (select id, DATA, update_dt, inspection_dt, check_dt,
RANK() OVER (PARTITION by ID
ORDER BY update_dt DESC, DATA
) as rank_upd,
RANK() OVER (PARTITION by ID
ORDER BY inspection_dt DESC, DATA
) as rank_insp,
FROM TABLE
) r
where r.rank_upd = 1 or r.rank_insp = 1;