Pokud je váš případ tak jednoduchý, jak naznačují hodnoty v příkladu, odpověď @Giorgos slouží dobře.
To však obvykle není tento případ . Pokud id sloupec je serial , nemůžete se spoléhat na předpoklad, že řádek s dřívějším time má také menší id .
Také time hodnoty (nebo timestamp jako pravděpodobně máte) mohou být snadno duplikáty, je třeba, aby bylo pořadí řazení jednoznačné.
Za předpokladu, že se může stát obojí a vy chcete id od řádku s nejstarším time za časový úsek (ve skutečnosti nejmenší id pro nejdříve čas , mohly by existovat remízy), tento dotaz by situaci správně řešil:
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, idbýt jednoznačný. Za předpokladu, že čas není jedinečný, přidejte (předpokládá se, že je jedinečný)idabyste se vyhnuli svévolným výsledkům – které by se mohly mezi dotazy záludně měnit. -
max(time) OVER (PARTITION BY way, grp):bezORDER BY, rám okna zabírá všechny řádky PARTITION, takže dostaneme absolutní maximum na časový úsek. -
Vnější vrstva dotazu je nezbytná pouze k vytvoření požadovaného pořadí řazení ve výsledku, protože jsme vázáni na jiný
ORDER BYv poddotazusubpomocíDISTINCT ON. Podrobnosti:
SQL Fiddle demonstrující případ použití.
Pokud hledáte optimalizaci výkonu, funkce plpgsql by v takovém případě mohla být rychlejší. Úzce související odpověď:
Stranou:nepoužívejte základní název typu time jako identifikátor (také rezervované slovo ve standardním SQL ).