sql >> Databasteknik >  >> RDS >> PostgreSQL

Så här grupperar du följande rader efter ett inte unikt värde

Om ditt fall är så enkelt som exempelvärdena antyder, @Giorgos svar tjänar fint.

Men det är vanligtvis inte fallet . Om id kolumnen är en serial , kan du inte lita på antagandet att en rad med en tidigare time har också ett mindre id .
Också time värden (eller timestamp som du förmodligen har) lätt kan vara dubbletter, du måste göra sorteringsordningen entydig.

Förutsatt att båda kan hända och att du vill ha id från raden med den tidigaste time per tidssegment (faktiskt den minsta id för den tidigaste tiden , det kan finnas kopplingar), skulle denna fråga hantera 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 att vara entydig. Förutsatt att tiden inte är unikt, lägg till (antaget unikt) id för att undvika godtyckliga resultat - som kan ändras mellan frågor på lömska sätt.

  • max(time) OVER (PARTITION BY way, grp) :utan ORDER BY , spänner fönsterramen över alla rader i PARTITIONEN, så vi får det absoluta maxvärdet per tidssegment.

  • Det yttre frågeskiktet är bara nödvändigt för att producera önskad sorteringsordning i resultatet, eftersom vi är bundna till en annan ORDER BY i underfrågan sub genom att använda DISTINCT ON . Detaljer:

SQL Fiddle demonstrerar användningsfallet.

Om du vill optimera prestanda kan en plpgsql-funktion vara snabbare i ett sådant fall. Närbesläktat svar:

Bortsett från:använd inte det grundläggande typnamnet time som identifierare (även ett reserverat ord i standard SQL ).



  1. Hur skickar man nuvarande radvärde i modal?

  2. Är en Load DATA utan en fil (dvs i minnet) möjlig för MySQL och Java?

  3. Släpp tabell från Oracle-databasen om tabell finns i sql-satsen

  4. VB.net SQL-sats för att fråga 1 år gammal tidsstämpel