PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Compter le total cumulé dans Postgresql

Avec des ensembles de données plus volumineux, les fonctions de fenêtre sont le moyen le plus efficace d'effectuer ce type de requêtes :la table ne sera analysée qu'une seule fois, au lieu d'une fois pour chaque date, comme le ferait une auto-jointure. Cela semble aussi beaucoup plus simple. :) PostgreSQL 8.4 et versions ultérieures prennent en charge les fonctions de fenêtre.

Voici à quoi cela ressemble :

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

Ici OVER crée la fenêtre ; ORDER BY created_at signifie qu'il doit résumer les comptes dans created_at commande.

Modifier : Si vous souhaitez supprimer les e-mails en double en une seule journée, vous pouvez utiliser sum(count(distinct email)) . Malheureusement, cela ne supprimera pas les doublons qui traversent des dates différentes.

Si vous souhaitez supprimer tous doublons, je pense que le plus simple est d'utiliser une sous-requête et DISTINCT ON . Cela attribuera les e-mails à leur date la plus ancienne (car je trie par created_at dans l'ordre croissant, il choisira le plus ancien) :

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;

Si vous créez un index sur (email, created_at) , cette requête ne devrait pas non plus être trop lente.

(Si vous voulez tester, voici comment j'ai créé l'exemple de jeu de données)

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