sql >> Databasteknik >  >> RDS >> PostgreSQL

Räkna ackumulerad summa i Postgresql

Med större datamängder, fönsterfunktioner är det mest effektiva sättet att utföra den här typen av frågor -- tabellen kommer bara att skannas en gång, istället för en gång för varje datum, som en självanslutning skulle göra. Det ser också mycket enklare ut. :) PostgreSQL 8.4 och uppåt har stöd för fönsterfunktioner.

Så här ser det ut:

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

Här OVER skapar fönstret; ORDER BY created_at betyder att den måste summera antalet i created_at beställa.

Redigera: Om du vill ta bort dubbletter av e-postmeddelanden inom en dag kan du använda sum(count(distinct email)) . Tyvärr tar detta inte bort dubbletter som korsar olika datum.

Om du vill ta bort alla dubbletter, jag tror att det enklaste är att använda en underfråga och DISTINCT ON . Detta kommer att tillskriva e-postmeddelanden till deras tidigaste datum (eftersom jag sorterar efter create_at i stigande ordning, kommer det att välja det tidigaste datumet):

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;

Om du skapar ett index på (email, created_at) , den här frågan bör inte vara för långsam heller.

(Om du vill testa är det så här jag skapade exempeldataset)

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. Hur current_date fungerar i PostgreSQL

  2. Spara tid Att köra Microsoft Access-rapporter med hjälp av filter i layoutvyn

  3. MySQL Fråga för att välja data från förra veckan?

  4. Förbisedda T-SQL-ädelstenar