Spørgsmålet er gammelt, men denne løsning er enklere og hurtigere end det, der hidtil er blevet postet:
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?
Hvis du tilføjer ORDER BY
til vinduesrammedefinitionen, hver næste række med en større ORDER BY
udtryk har en senere rammestart. Hverken min()
heller ikke first_value()
kan returnere det "første" tidsstempel for hele partitionen derefter. Uden ORDER BY
alle rækker i den samme partition er peers og du får det ønskede resultat.
Din tilføjede ORDER BY
virker (ikke den i vinduesrammens definition, den ydre), men det ser ikke ud til at give mening og gør forespørgslen dyrere. Du skal nok bruge en ORDER BY
klausul, der stemmer overens med din vinduesrammedefinition for at undgå yderligere sorteringsomkostninger:
...
ORDER BY batch, b.machine_id, timestamp_sta, timestamp_stp;
Jeg kan ikke se behovet for DISTINCT
i denne forespørgsel. Du kan bare tilføje det, hvis du rent faktisk har brug for det. Eller DISTINCT ON ()
. Men så ORDER BY
klausul bliver endnu mere relevant. Se:
Hvis du har brug for nogle andre kolonne(r) fra samme række (mens du stadig sorterer efter tidsstempler), din idé med FIRST_VALUE()
og LAST_VALUE()
kan være vejen at gå. Du skal sandsynligvis tilføje dette til vinduesrammedefinitionen så :
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
Se: