De vraag is oud, maar deze oplossing is eenvoudiger en sneller dan wat er tot nu toe is gepost:
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?
Als u ORDER BY
. toevoegt naar de raamkozijndefinitie, elke volgende rij met een grotere ORDER BY
expressie heeft een latere framestart. Geen van beide min()
noch first_value()
kan dan de "eerste" tijdstempel voor de hele partitie retourneren. Zonder ORDER BY
alle rijen van dezelfde partitie zijn peers en je krijgt het gewenste resultaat.
Uw toegevoegde ORDER BY
werkt (niet die in de raamkozijndefinitie, de buitenste), maar lijkt niet logisch en maakt de vraag duurder. U moet waarschijnlijk een ORDER BY
. gebruiken clausule die overeenkomt met uw raamkozijndefinitie om extra sorteerkosten te voorkomen:
...
ORDER BY batch, b.machine_id, timestamp_sta, timestamp_stp;
Ik zie de noodzaak van DISTINCT
niet in in deze vraag. Je kunt het gewoon toevoegen als je het echt nodig hebt. Of DISTINCT ON ()
. Maar dan de ORDER BY
clausule wordt nog relevanter. Zie:
Als je een of meer andere kolom(men) uit dezelfde rij nodig hebt (terwijl je nog steeds op tijdstempels sorteert), je idee met FIRST_VALUE()
en LAST_VALUE()
misschien de weg te gaan. Je zou dit waarschijnlijk moeten toevoegen aan de raamkozijndefinitie dan :
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
Zie: