sql >> Database >  >> RDS >> PostgreSQL

Eerste en laatste waarde van vensterfunctie in één rij in PostgreSQL

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:



  1. Waar clausule werkt werkt niet op tinyint

  2. Kan categorie-object niet krijgen in sommige sjablonen van WooCommerce

  3. Externe MySql-verbinding vanaf een andere server

  4. Datum retourneert null-waarden na het indienen van het bewerkingsformulier in php