sql >> Databáze >  >> RDS >> PostgreSQL

Jak přidat průběžný počet do řádků v „sérii“ po sobě jdoucích dnů

Na základě této tabulky (bez použití klíčového slova SQL "date" jako název sloupce.):

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

Dotaz:

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;

Odečtením date z jiného date dává integer . Protože hledáte po sobě jdoucí dny, každý další řádek bude o jednu větší . Pokud odečteme row_number() z toho celý pruh skončí ve stejné skupině (grp ) za pid . Pak je snadné rozdělit počet na skupinu.

grp se počítá se dvěma odečítáními, které by měly být nejrychlejší. Stejně rychlá alternativa by mohla být:

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

Jedno násobení, jedno odčítání. Zřetězení a odlévání strun je dražší. Otestujte pomocí EXPLAIN ANALYZE .

Nezapomeňte rozdělit podle pid navíc v obě kroky, nebo neúmyslně smícháte skupiny, které by měly být odděleny.

Pomocí poddotazu, protože ten je obvykle rychlejší než CTE . Není zde nic, co by prostý poddotaz nedokázal.

A protože jste to zmínil:dense_rank() zjevně není zde nutné. Základní row_number() dělá svou práci.



  1. PostGIS ekvivalent ArcMap Union

  2. Nastavte výchozí LIMIT v PDO/MySQL, když není nastaven žádný LIMIT

  3. Jak používat tipy obrazovky Access 2019

  4. Odstranění profilu pošty databáze v SQL Server (T-SQL)