PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Première et dernière valeur de la fonction de fenêtre dans une ligne dans PostgreSQL

La question est ancienne, mais cette solution est plus simple et plus rapide que ce qui a été publié jusqu'à présent :

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 vous ajoutez ORDER BY à la définition du cadre de la fenêtre, chaque ligne suivante avec un ORDER BY supérieur l'expression a un début de cadre ultérieur. Ni min() ni first_value() peut alors renvoyer le "premier" horodatage pour toute la partition. Sans ORDER BY toutes les lignes de la même partition sont des pairs et vous obtenez le résultat souhaité.

Votre ORDER BY ajouté fonctionne (pas celui de la définition du cadre de la fenêtre, celui de l'extérieur), mais ne semble pas logique et rend la requête plus coûteuse. Vous devriez probablement utiliser un ORDER BY clause qui correspond à la définition de votre cadre de fenêtre pour éviter des coûts de tri supplémentaires :

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

Je ne vois pas la nécessité de DISTINCT dans cette requête. Vous pouvez simplement l'ajouter si vous en avez réellement besoin. Ou DISTINCT ON () . Mais alors le ORDER BY clause devient encore plus pertinente. Voir :

Si vous avez besoin d'autres colonnes de la même ligne (tout en triant par horodatage), votre idée avec FIRST_VALUE() et LAST_VALUE() pourrait être la voie à suivre. Vous devrez probablement ajouter ceci à la définition du cadre de la fenêtre alors :

ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING

Voir :