sql >> Databáze >  >> RDS >> PostgreSQL

Jak seskupit následující řádky podle nejedinečné hodnoty

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) :bez ORDER 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 poddotazu sub 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 ).



  1. PHP Cookie pro udržení přihlášeného uživatele – je to dostatečně bezpečné?

  2. Prostorový index v MySQL – CHYBA – Nelze získat objekt geometrie z dat, která odesíláte do pole GEOMETRY

  3. Zvyšte rozsah ID ActiveModel na 8 bajtů

  4. Jak formátovat klauzuli SQL IN pomocí Pythonu