Въпросът е стар, но това решение е по-просто и по-бързо от това, което е публикувано досега:
SELECT b.machine_id
, batch
, timestamp_sta
, timestamp_stp
, min(timestamp_sta) OVER w AS batch_start
, max(timestamp_stp) OVER w AS batch_end
FROM db_data.sta_stp a
JOIN db_data.ll_lu b ON a.ll_lu_id = b.id
WINDOW w AS (PARTITION BY batch, b.machine_id) -- No ORDER BY !
ORDER BY timestamp_sta, batch, machine_id; -- why this ORDER BY?
Ако добавите ORDER BY
към дефиницията на рамката на прозореца, всеки следващ ред с по-голям ORDER BY
изразът има по-късен старт на рамката. Нито min()
нито first_value()
тогава може да върне "първото" времево клеймо за целия дял. Без ORDER BY
всички редове на един и същи дял са равностойни и ще получите желания резултат.
Вашият добавен ORDER BY
работи (не тази в дефиницията на рамката на прозореца, а външната), но изглежда няма смисъл и оскъпява заявката. Вероятно трябва да използвате ORDER BY
клауза, която е в съгласие с вашата дефиниция на рамката на прозореца, за да се избегнат допълнителни разходи за сортиране:
...
ORDER BY batch, b.machine_id, timestamp_sta, timestamp_stp;
Не виждам нужда от DISTINCT
в тази заявка. Можете просто да го добавите, ако наистина имате нужда от него. Или DISTINCT ON ()
. Но след това ORDER BY
клауза става още по-актуална. Вижте:
Ако имате нужда от друга колона(и) от същия ред (докато все още сортирате по времеви клейма), вашата идея с FIRST_VALUE()
и LAST_VALUE()
може да е правилният начин. Вероятно ще трябва да добавите това към дефиницията на рамката на прозореца тогава :
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
Вижте: