PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Conta il totale cumulativo in Postgresql

Con set di dati più grandi, funzioni finestra sono il modo più efficiente per eseguire questo tipo di query:la tabella verrà scansionata solo una volta, invece di una per ogni data, come farebbe un self-join. Sembra anche molto più semplice. :) PostgreSQL 8.4 e versioni successive supportano le funzioni della finestra.

Ecco come appare:

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

Qui OVER crea la finestra; ORDER BY created_at significa che deve sommare i conteggi in created_at ordine.

Modifica: Se desideri rimuovere le email duplicate entro un solo giorno, puoi utilizzare sum(count(distinct email)) . Sfortunatamente questo non rimuoverà i duplicati che attraversano date diverse.

Se desideri rimuovere tutto duplicati, penso che il modo più semplice sia usare una sottoquery e DISTINCT ON . Questo attribuirà le email alla loro prima data (perché sto ordinando per create_at in ordine crescente, sceglierà la prima):

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;

Se crei un indice su (email, created_at) , anche questa query non dovrebbe essere troppo lenta.

(Se vuoi testare, ecco come ho creato il set di dati di esempio)

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);