बड़े डेटासेट के साथ, विंडो फ़ंक्शन इस प्रकार के प्रश्नों को करने का सबसे कारगर तरीका है -- तालिका को प्रत्येक तिथि के लिए एक बार के बजाय केवल एक बार स्कैन किया जाएगा, जैसे कि एक सेल्फ-जॉइन करेगा। यह दिखने में भी काफी सिंपल लगता है। :) PostgreSQL 8.4 और बाद वाले वर्शन में विंडो फंक्शन के लिए सपोर्ट है।
यह ऐसा दिखता है:
SELECT created_at, sum(count(email)) OVER (ORDER BY created_at)
FROM subscriptions
GROUP BY created_at;
यहां OVER
खिड़की बनाता है; ORDER BY created_at
इसका मतलब है कि इसे created_at
. में गणनाओं का योग करना होगा आदेश।
संपादित करें: अगर आप एक ही दिन में डुप्लीकेट ईमेल हटाना चाहते हैं, तो आप sum(count(distinct email))
का उपयोग कर सकते हैं . दुर्भाग्य से यह अलग-अलग तिथियों को पार करने वाले डुप्लिकेट को नहीं हटाएगा।
अगर आप सभी को हटाना चाहते हैं डुप्लिकेट, मुझे लगता है कि सबक्वेरी और DISTINCT ON
. का उपयोग करना सबसे आसान है . यह ईमेल को उनकी शुरुआती तारीख का श्रेय देगा (क्योंकि मैं create_at के अनुसार आरोही क्रम में क्रमबद्ध कर रहा हूं, यह जल्द से जल्द एक को चुनेगा):
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;
अगर आप (email, created_at)
. पर एक इंडेक्स बनाते हैं , यह क्वेरी बहुत धीमी भी नहीं होनी चाहिए।
(यदि आप परीक्षण करना चाहते हैं, तो मैंने नमूना डेटासेट इस प्रकार बनाया है)
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);