PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Jak pogrupować kolejne wiersze według nieunikalnej wartości

Jeśli Twoja sprawa jest tak prosta, jak sugerują wartości przykładu, odpowiedź @Giorgos służy ładnie.

Jednak zazwyczaj tak nie jest . Jeśli id kolumna jest serial , nie można polegać na założeniu, że wiersz z wcześniejszym time ma również mniejszy id .
Ponadto time wartości (lub timestamp tak jak prawdopodobnie masz) mogą łatwo być duplikatami, musisz uczynić porządek sortowania jednoznacznym.

Zakładając, że jedno i drugie może się zdarzyć i potrzebujesz id z wiersza z najwcześniejszym time na wycinek czasu (w rzeczywistości najmniejszy id najwcześniej czas , mogą być remisy), to zapytanie rozwiązałoby sytuację prawidłowo:

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 być jednoznacznym. Zakładając, że czas nie unikalny, dodaj (zakładany unikalny) id aby uniknąć arbitralnych wyników - które mogą zmieniać się między zapytaniami w podstępny sposób.

  • max(time) OVER (PARTITION BY way, grp) :bez ORDER BY , rama okna obejmuje wszystkie wiersze PARTYCJI, więc otrzymujemy absolutne maksimum na wycinek czasu.

  • Zewnętrzna warstwa zapytania jest konieczna tylko do uzyskania pożądanej kolejności sortowania w wyniku, ponieważ jesteśmy związani z innym ORDER BY w podzapytaniu sub za pomocą DISTINCT ON . Szczegóły:

Skrzypce SQL zademonstrowanie przypadku użycia.

Jeśli chcesz zoptymalizować wydajność, funkcja plpgsql może być w takim przypadku szybsza. Ściśle powiązana odpowiedź:

Poza tym:nie używaj podstawowej nazwy typu time jako identyfikator (również zastrzeżone słowo w standardowym SQL ).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak używać Spring StandardPasswordEncode i Get Salt Generate?

  2. Problem do wstawienia za pomocą psycopg

  3. Travis CI:FATAL:rola nie istnieje

  4. żądanie postgresql dotyczące kilku schematów

  5. Kolumny MySQL z DEFAULT NULL - stylistyczny wybór, czy to prawda?