Si votre cas est aussi simple que le suggèrent les exemples de valeurs, @Giorgos' answer sert bien.
Cependant, ce n'est généralement pas le cas . Si l'id
la colonne est un serial
, vous ne pouvez pas partir du principe qu'une ligne avec un time
antérieur a également un id
plus petit .
Aussi, time
valeurs (ou timestamp
comme vous l'avez probablement fait) peuvent facilement être des doublons, vous devez rendre l'ordre de tri sans ambiguïté.
En supposant que les deux peuvent se produire et que vous voulez le id
à partir de la ligne avec la time
la plus ancienne par tranche de temps (en fait, le plus petit id
au plus tôt temps , il pourrait y avoir des égalités), cette requête traiterait correctement la situation :
SELECT *
FROM (
SELECT DISTINCT ON (way, grp)
id, way, time AS time_from
, max(time) OVER (PARTITION BY way, grp) AS time_to
FROM (
SELECT *
, row_number() OVER (ORDER BY time, id) -- id as tie breaker
- row_number() OVER (PARTITION BY way ORDER BY time, id) AS grp
FROM table1
) t
ORDER BY way, grp, time, id
) sub
ORDER BY time_from, id;
-
ORDER BY time, id
être sans ambiguïté. En supposant que le temps n'est pas unique, ajoutez le (supposé unique)id
pour éviter des résultats arbitraires - qui pourraient changer entre les requêtes de manière sournoise. -
max(time) OVER (PARTITION BY way, grp)
:sansORDER BY
, le cadre de la fenêtre s'étend sur toutes les lignes de la PARTITION, nous obtenons donc le maximum absolu par tranche de temps. -
La couche de requête externe n'est nécessaire que pour produire l'ordre de tri souhaité dans le résultat, puisque nous sommes liés à un
ORDER BY
différent dans la sous-requêtesub
en utilisantDISTINCT ON
. Détails :
SQL Fiddle démontrant le cas d'utilisation.
Si vous cherchez à optimiser les performances, une fonction plpgsql pourrait être plus rapide dans un tel cas. Réponse étroitement liée :
A part :n'utilisez pas le nom de type de base time
comme identifiant (également un mot réservé en SQL standard ).