PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Contar o total cumulativo no Postgresql


Com conjuntos de dados maiores, funções de janela são a maneira mais eficiente de realizar esses tipos de consultas -- a tabela será verificada apenas uma vez, em vez de uma vez para cada data, como faria uma autojunção. Também parece muito mais simples. :) PostgreSQL 8.4 e superior tem suporte para funções de janela.

Isto é o que parece:
SELECT created_at, sum(count(email)) OVER (ORDER BY created_at)
FROM subscriptions
GROUP BY created_at;

Aqui OVER cria a janela; ORDER BY created_at significa que tem que somar as contagens em created_at pedido.

Editar: Se você deseja remover e-mails duplicados em um único dia, você pode usar sum(count(distinct email)) . Infelizmente, isso não removerá duplicatas que cruzam datas diferentes.

Se você deseja remover todos duplicatas, acho que o mais fácil é usar uma subconsulta e DISTINCT ON . Isso atribuirá os emails à data mais antiga (porque estou classificando por created_at em ordem crescente, ele escolherá o mais antigo):
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 você criar um índice em (email, created_at) , essa consulta também não deve ser muito lenta.

(Se você quiser testar, foi assim que criei o conjunto de dados de exemplo)
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);