Въпросът е стар, но това решение е по-просто и по-бързо от това, което е публикувано досега:
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
Вижте: