Dengan kumpulan data yang lebih besar, fungsi jendela adalah cara paling efisien untuk melakukan kueri semacam ini -- tabel hanya akan dipindai sekali, bukan sekali untuk setiap tanggal, seperti yang akan dilakukan oleh self-join. Itu juga terlihat jauh lebih sederhana. :) PostgreSQL 8.4 dan yang lebih baru memiliki dukungan untuk fungsi jendela.
Ini penampakannya:
SELECT created_at, sum(count(email)) OVER (ORDER BY created_at)
FROM subscriptions
GROUP BY created_at;
Di sini OVER
membuat jendela; ORDER BY created_at
berarti ia harus menjumlahkan jumlah dalam created_at
pesan.
Sunting: Jika Anda ingin menghapus email duplikat dalam satu hari, Anda dapat menggunakan sum(count(distinct email))
. Sayangnya, ini tidak akan menghapus duplikat yang melewati tanggal yang berbeda.
Jika Anda ingin menghapus semua duplikat, saya pikir yang paling mudah adalah menggunakan subquery dan DISTINCT ON
. Ini akan mengatribusikan email ke tanggal paling awal (karena saya mengurutkan berdasarkan create_at dalam urutan menaik, itu akan memilih yang paling awal):
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;
Jika Anda membuat indeks di (email, created_at)
, kueri ini juga tidak boleh terlalu lambat.
(Jika Anda ingin menguji, ini adalah cara saya membuat kumpulan data sampel)
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);