sql >> Base de Datos >  >> RDS >> PostgreSQL

Primer y último valor de la función de ventana en una fila en PostgreSQL

La pregunta es antigua, pero esta solución es más simple y rápida que lo que se ha publicado hasta ahora:

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?

Si agrega ORDER BY a la definición del marco de la ventana, cada fila siguiente con un mayor ORDER BY expresión tiene un inicio de cuadro posterior. Ni min() ni first_value() puede devolver la "primera" marca de tiempo para toda la partición. Sin ORDER BY todas las filas de la misma partición son pares y obtienes el resultado deseado.

Su ORDER BY agregado funciona (no el de la definición del marco de la ventana, el exterior), pero no parece tener sentido y encarece la consulta. Probablemente deberías usar un ORDER BY cláusula que concuerde con la definición del marco de su ventana para evitar costos de clasificación adicionales:

... 
ORDER BY batch, b.machine_id, timestamp_sta, timestamp_stp;

No veo la necesidad de DISTINCT en esta consulta. Puede agregarlo si realmente lo necesita. O DISTINCT ON () . Pero entonces el ORDER BY cláusula se vuelve aún más relevante. Ver:

Si necesita otras columnas de la misma fila (sin dejar de ordenar por marcas de tiempo), su idea con FIRST_VALUE() y LAST_VALUE() podría ser el camino a seguir. Probablemente necesite agregar esto a la definición del marco de la ventana luego :

ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING

Ver: