sql >> Databasteknik >  >> RDS >> PostgreSQL

Första och sista värdet för fönsterfunktion i en rad i PostgreSQL

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 :

ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING

Se:



  1. Hur kan man köra flera satser i en fråga med Rails?

  2. Hur kan jag analysera JSON-sträng i PL/SQL

  3. Kan inte komma åt tillfälliga tabeller från en funktion

  4. Syntaxfel med emulering av skapa användare om det inte finns