Bei größeren Datensätzen Fensterfunktionen sind die effizienteste Art, diese Art von Abfragen durchzuführen – die Tabelle wird nur einmal gescannt, anstatt einmal für jedes Datum, wie es bei einem Self-Join der Fall wäre. Es sieht auch viel einfacher aus. :) PostgreSQL 8.4 und höher unterstützen Fensterfunktionen.
So sieht es aus:
SELECT created_at, sum(count(email)) OVER (ORDER BY created_at)
FROM subscriptions
GROUP BY created_at;
Hier OVER
erstellt das Fenster; ORDER BY created_at
bedeutet, dass die Zählungen in created_at
summiert werden müssen bestellen.
Bearbeiten: Wenn Sie doppelte E-Mails innerhalb eines einzigen Tages entfernen möchten, können Sie sum(count(distinct email))
verwenden . Leider werden dadurch keine Duplikate entfernt, die sich über verschiedene Daten erstrecken.
Wenn Sie alle entfernen möchten Duplikate, denke ich, ist es am einfachsten, eine Unterabfrage und DISTINCT ON
zu verwenden . Dadurch werden E-Mails ihrem frühesten Datum zugeordnet (da ich in aufsteigender Reihenfolge nach created_at sortiere, wird das früheste ausgewählt):
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;
Wenn Sie einen Index auf (email, created_at)
erstellen , diese Abfrage sollte auch nicht zu langsam sein.
(Wenn Sie es testen möchten, so habe ich den Beispieldatensatz erstellt)
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);