Jeśli Twoja sprawa jest tak prosta, jak sugerują wartości przykładu, odpowiedź @Giorgos służy ładnie.
Jednak zazwyczaj tak nie jest . Jeśli id kolumna jest serial , nie można polegać na założeniu, że wiersz z wcześniejszym time ma również mniejszy id .
Ponadto time wartości (lub timestamp tak jak prawdopodobnie masz) mogą łatwo być duplikatami, musisz uczynić porządek sortowania jednoznacznym.
Zakładając, że jedno i drugie może się zdarzyć i potrzebujesz id z wiersza z najwcześniejszym time na wycinek czasu (w rzeczywistości najmniejszy id najwcześniej czas , mogą być remisy), to zapytanie rozwiązałoby sytuację prawidłowo:
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, idbyć jednoznacznym. Zakładając, że czas nie unikalny, dodaj (zakładany unikalny)idaby uniknąć arbitralnych wyników - które mogą zmieniać się między zapytaniami w podstępny sposób. -
max(time) OVER (PARTITION BY way, grp):bezORDER BY, rama okna obejmuje wszystkie wiersze PARTYCJI, więc otrzymujemy absolutne maksimum na wycinek czasu. -
Zewnętrzna warstwa zapytania jest konieczna tylko do uzyskania pożądanej kolejności sortowania w wyniku, ponieważ jesteśmy związani z innym
ORDER BYw podzapytaniusubza pomocąDISTINCT ON. Szczegóły:
Skrzypce SQL zademonstrowanie przypadku użycia.
Jeśli chcesz zoptymalizować wydajność, funkcja plpgsql może być w takim przypadku szybsza. Ściśle powiązana odpowiedź:
Poza tym:nie używaj podstawowej nazwy typu time jako identyfikator (również zastrzeżone słowo w standardowym SQL ).