sql >> Database >  >> RDS >> PostgreSQL

Hoe de volgende rijen te groeperen op niet-unieke waarde

Als uw zaak zo eenvoudig is als de voorbeeldwaarden suggereren, @Giorgos' antwoord serveert mooi.

Dat is echter meestal niet het geval . Als de id kolom is een serial , kunt u er niet van uitgaan dat een rij met een eerdere time heeft ook een kleinere id .
Ook time waarden (of timestamp zoals je waarschijnlijk hebt) kunnen gemakkelijk duplicaten zijn, je moet de sorteervolgorde ondubbelzinnig maken.

Ervan uitgaande dat beide kunnen gebeuren, en u wilt de id uit de rij met de vroegste time per tijdschijf (eigenlijk de kleinste id voor de vroegste tijd , er kunnen verbanden zijn), zou deze vraag de situatie goed behandelen:

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 eenduidig ​​te zijn. Ervan uitgaande dat de tijd niet . is uniek, voeg de (veronderstelde unieke) id . toe om willekeurige resultaten te vermijden - die op stiekeme manieren tussen zoekopdrachten kunnen veranderen.

  • max(time) OVER (PARTITION BY way, grp) :zonder ORDER BY , het raamkozijn omspant alle rijen van de PARTITION, dus we krijgen het absolute maximum per tijdsegment.

  • De buitenste querylaag is alleen nodig om de gewenste sorteervolgorde in het resultaat te produceren, aangezien we gebonden zijn aan een andere ORDER BY in de subquery sub door DISTINCT ON . te gebruiken . Details:

SQL Fiddle de use case demonstreren.

Als u de prestaties wilt optimaliseren, kan een plpgsql-functie in zo'n geval sneller zijn. Nauw verwant antwoord:

Terzijde:gebruik niet de basistypenaam time als identifier (ook een gereserveerd woord in standaard SQL ).



  1. MyBatis extra komma in updatequery

  2. Hoe voer ik een SQL-bestand uit in PostgreSQL met behulp van een Linux-terminal?

  3. Ontvang records voor de min datetime van elke persoon voor elke dag

  4. vreemd gedrag van SQL Server wanneer de waarden van somknooppunten in XML