Frågan är gammal, men den här lösningen är enklare och snabbare än vad som har postats hittills:
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?
Om du lägger till ORDER BY
till fönsterramsdefinitionen, varje nästa rad med en större ORDER BY
uttryck har en senare ramstart. Varken min()
inte heller first_value()
kan returnera den "första" tidsstämpeln för hela partitionen då. Utan ORDER BY
alla rader i samma partition är peers och du får önskat resultat.
Din tillagda ORDER BY
fungerar (inte den i fönsterramsdefinitionen, den yttre), men verkar inte vara vettig och gör frågan dyrare. Du bör förmodligen använda en ORDER BY
klausul som överensstämmer med din fönsterramsdefinition för att undvika extra sorteringskostnader:
...
ORDER BY batch, b.machine_id, timestamp_sta, timestamp_stp;
Jag ser inte behovet av DISTINCT
i denna fråga. Du kan bara lägga till det om du verkligen behöver det. Eller DISTINCT ON ()
. Men sedan ORDER BY
klausulen blir ännu mer relevant. Se:
Om du behöver några andra kolumner från samma rad (medan du fortfarande sorterar efter tidsstämplar), din idé med FIRST_VALUE()
och LAST_VALUE()
kan vara vägen att gå. Du skulle förmodligen behöva lägga till detta i fönsterramsdefinitionen då :
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
Se: