sql >> Base de Datos >  >> RDS >> PostgreSQL

Cuente el total acumulativo en Postgresql

Con conjuntos de datos más grandes, funciones de ventana son la forma más eficiente de realizar este tipo de consultas:la tabla se escaneará solo una vez, en lugar de una vez para cada fecha, como lo haría una autounión. También parece mucho más simple. :) PostgreSQL 8.4 y versiones posteriores tienen soporte para funciones de ventana.

Así es como se ve:

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

Aquí OVER crea la ventana; ORDER BY created_at significa que tiene que resumir los recuentos en created_at orden.

Editar: Si desea eliminar correos electrónicos duplicados en un solo día, puede usar sum(count(distinct email)) . Desafortunadamente, esto no eliminará los duplicados que crucen fechas diferentes.

Si desea eliminar todos duplicados, creo que lo más fácil es usar una subconsulta y DISTINCT ON . Esto atribuirá los correos electrónicos a su fecha más antigua (porque los ordeno por created_at en orden ascendente, elegirá la más antigua):

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 crea un índice en (email, created_at) , esta consulta tampoco debería ser demasiado lenta.

(Si desea probar, así es como creé el conjunto de datos de muestra)

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