Om ditt fall är så enkelt som exempelvärdena antyder, @Giorgos svar tjänar fint.
Men det är vanligtvis inte fallet . Om id kolumnen är en serial , kan du inte lita på antagandet att en rad med en tidigare time har också ett mindre id .
Också time värden (eller timestamp som du förmodligen har) lätt kan vara dubbletter, du måste göra sorteringsordningen entydig.
Förutsatt att båda kan hända och att du vill ha id från raden med den tidigaste time per tidssegment (faktiskt den minsta id för den tidigaste tiden , det kan finnas kopplingar), skulle denna fråga hantera situationen korrekt:
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, idatt vara entydig. Förutsatt att tiden inte är unikt, lägg till (antaget unikt)idför att undvika godtyckliga resultat - som kan ändras mellan frågor på lömska sätt. -
max(time) OVER (PARTITION BY way, grp):utanORDER BY, spänner fönsterramen över alla rader i PARTITIONEN, så vi får det absoluta maxvärdet per tidssegment. -
Det yttre frågeskiktet är bara nödvändigt för att producera önskad sorteringsordning i resultatet, eftersom vi är bundna till en annan
ORDER BYi underfrågansubgenom att användaDISTINCT ON. Detaljer:
SQL Fiddle demonstrerar användningsfallet.
Om du vill optimera prestanda kan en plpgsql-funktion vara snabbare i ett sådant fall. Närbesläktat svar:
Bortsett från:använd inte det grundläggande typnamnet time som identifierare (även ett reserverat ord i standard SQL ).