sql >> Database >  >> RDS >> PostgreSQL

Tel cumulatief totaal in Postgresql

Bij grotere datasets, vensterfuncties zijn de meest efficiënte manier om dit soort zoekopdrachten uit te voeren -- de tabel wordt slechts één keer gescand, in plaats van één keer voor elke datum, zoals een self-join zou doen. Het ziet er ook een stuk eenvoudiger uit. :) PostgreSQL 8.4 en hoger hebben ondersteuning voor vensterfuncties.

Zo ziet het eruit:

SELECT created_at, sum(count(email)) OVER (ORDER BY created_at)
FROM subscriptions
GROUP BY created_at;

Hier OVER maakt het venster; ORDER BY created_at betekent dat het de tellingen moet optellen in created_at bestellen.

Bewerken: Als u dubbele e-mails binnen één dag wilt verwijderen, kunt u sum(count(distinct email)) gebruiken . Helaas worden hiermee geen duplicaten verwijderd die verschillende datums overschrijden.

Als u alle wilt verwijderen duplicaten, ik denk dat het het gemakkelijkst is om een ​​subquery te gebruiken en DISTINCT ON . Hierdoor worden e-mails toegeschreven aan hun vroegste datum (omdat ik sorteer op create_at in oplopende volgorde, wordt de vroegste gekozen):

SELECT created_at, sum(count(email)) OVER (ORDER BY created_at)
FROM (
    SELECT DISTINCT ON (email) created_at, email
    FROM subscriptions ORDER BY email, created_at
) AS subq
GROUP BY created_at;

Als u een index maakt op (email, created_at) , moet deze zoekopdracht ook niet te langzaam zijn.

(Als je wilt testen, zo heb ik de voorbeelddataset gemaakt)

create table subscriptions as
   select date '2000-04-04' + (i/10000)::int as created_at,
          '[email protected]' || (i%700000)::text as email
   from generate_series(1,1000000) i;
create index on subscriptions (email, created_at);


  1. PolyBase verbinden met Salesforce.com

  2. pgAdmin-alternatieven - GUI ClusterControl voor PostgreSQL-databasebeheer

  3. Waarom zijn er hiaten in mijn IDENTITY-kolomwaarden?

  4. SYSDATETIME() vs GETDATE() in SQL Server:wat is het verschil?