Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>With larger datasets, <a href="https://www.postgresql.org/docs/current/static/tutorial-window.html" rel="noreferrer"><strong>window functions</strong></a> are the most efficient way to perform these kinds of queries -- the table will be scanned only once, instead of once for each date, like a self-join would do. It also looks a lot simpler. :) PostgreSQL 8.4 and up have support for window functions.</p> <p>This is what it looks like:</p> <pre><code>SELECT created_at, sum(count(email)) OVER (ORDER BY created_at) FROM subscriptions GROUP BY created_at; </code></pre> <p>Here <code>OVER</code> creates the window; <code>ORDER BY created_at</code> means that it has to sum up the counts in <code>created_at</code> order.</p> <hr> <p><strong>Edit:</strong> If you want to remove duplicate emails within a single day, you can use <code>sum(count(distinct email))</code>. Unfortunately this won't remove duplicates that cross different dates.</p> <p>If you want to remove <em>all</em> duplicates, I think the easiest is to use a subquery and <code>DISTINCT ON</code>. This will attribute emails to their earliest date (because I'm sorting by created_at in ascending order, it'll choose the earliest one):</p> <pre><code>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; </code></pre> <p>If you create an index on <code>(email, created_at)</code>, this query shouldn't be too slow either.</p> <hr> <p>(If you want to test, this is how I created the sample dataset)</p> <pre><code>create table subscriptions as select date '2000-04-04' + (i/10000)::int as created_at, 'foofoobar@foobar.com' || (i%700000)::text as email from generate_series(1,1000000) i; create index on subscriptions (email, created_at); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload