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

Jak dodać bieżącą liczbę do rzędów w „smianie” kolejnych dni?

Opierając się na tej tabeli (bez użycia słowa kluczowego SQL „date” jako nazwę kolumny.):

CREATE TABLE tbl(
  pid int
, the_date date
, PRIMARY KEY (pid, the_date)
);

Zapytanie:

SELECT pid, the_date
     , row_number() OVER (PARTITION BY pid, grp ORDER BY the_date) AS in_streak
FROM  (
   SELECT *
        , the_date - '2000-01-01'::date
        - row_number() OVER (PARTITION BY pid ORDER BY the_date) AS grp
   FROM   tbl
) sub
ORDER  BY pid, the_date;

Odejmowanie date z innej date zwraca integer . Ponieważ szukasz kolejnych dni, każdy kolejny wiersz byłby większy o jeden . Jeśli odejmiemy row_number() od tego cała passa kończy się w tej samej grupie (grp ) na pid . Wtedy łatwo jest rozdzielić liczbę na grupę.

grp jest obliczany za pomocą dwóch odejmowań, które powinny być najszybsze. Równie szybką alternatywą może być:

the_date - row_number() OVER (PARTITION BY pid ORDER BY the_date) * interval '1d' AS grp

Jedno mnożenie, jedno odejmowanie. Łączenie i rzutowanie ciągów jest droższe. Przetestuj za pomocą EXPLAIN ANALYZE .

Nie zapomnij podzielić według pid dodatkowo w obu kroki lub przypadkowo wymieszasz grupy, które powinny być rozdzielone.

Korzystanie z podzapytania, ponieważ jest to zwykle szybsze niż CTE . Nie ma tu niczego, czego nie mogłoby zrobić zwykłe podzapytanie.

A skoro o tym wspomniałeś:dense_rank() jest oczywiście nie konieczne tutaj. Podstawowe row_number() wykonuje swoją pracę.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. pg_dump:[archiver (db)] zapytanie nie powiodło się:BŁĄD:odmowa uprawnień dla relacji abouts

  2. Błędy bazy danych w Django podczas używania wątków

  3. Tabela przestawna dla danych na godzinę

  4. Railsy:rake db:create:all nie łączy się z bazą danych PostgreSQL

  5. Komunikat 28000:brak wpisu pg_hba.conf dla hosta \xx.xxx.xxx.xxxx\, użytkownik \User, baza danych \databasename\, SSL wyłączony