sql >> Database teknologi >  >> RDS >> PostgreSQL

Sådan grupperes følgende rækker efter ikke-entydig værdi

Hvis din sag er så enkel, som eksempelværdierne antyder, @Giorgos' svar tjener pænt.

Det er dog typisk ikke tilfældet . Hvis id kolonne er en serial , kan du ikke stole på den antagelse, at en række med et tidligere time har også et mindre id .
Også time værdier (eller timestamp som du sikkert har) nemt kan være dubletter, skal du gøre sorteringsrækkefølgen utvetydig.

Forudsat at begge dele kan ske, og du vil have id fra rækken med det tidligste time pr. tidsudsnit (faktisk den mindste id for det tidligste tidspunkt , der kunne være bånd), ville denne forespørgsel håndtere 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, id at være entydig. Forudsat at tiden ikke er unikt, tilføj (antaget unikt) id for at undgå vilkårlige resultater - det kan ændre sig mellem forespørgsler på luskede måder.

  • max(time) OVER (PARTITION BY way, grp) :uden ORDER BY , spænder vinduesrammen over alle rækker i PARTITIONEN, så vi får det absolutte maksimum pr. tidsudsnit.

  • Det ydre forespørgselslag er kun nødvendigt for at producere den ønskede sorteringsrækkefølge i resultatet, da vi er bundet til en anden ORDER BY i underforespørgslen sub ved at bruge DISTINCT ON . Detaljer:

SQL Fiddle demonstrerer brugssagen.

Hvis du ønsker at optimere ydeevnen, kan en plpgsql-funktion være hurtigere i et sådant tilfælde. Nært beslægtet svar:

Til side:Brug ikke det grundlæggende typenavn time som identifikator (også et reserveret ord i standard SQL ).



  1. Sådan gør du split og left join i oracle

  2. Bruger samme kolonne flere gange i WHERE-sætning

  3. deltage med opslag og gruppeby

  4. MySQL-replikeringshastighed