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, id
být jednoznačný. Za předpokladu, že čas není jedinečný, přidejte (předpokládá se, že je jedinečný)id
abyste 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 BY
v poddotazusub
pomocí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 ).