 <p><sup>Updated after rereading the question.</sup><br> You are mixing <code>GROUP BY</code> and <code>DISTINCT ON</code>. What you want (how I understand it) can be done with a <a href="http://www.postgresql.org/docs/current/interactive/tutorial-window.html" rel="nofollow">window function</a> combined with a <code>DISTINCT ON</code>:</p> <pre><code>SELECT DISTINCT ON (a) a, b, c , count(d) OVER (PARTITION BY a, b, c) AS d_ct , e FROM tbl ORDER BY a, d_ct DESC; </code></pre> <p>Window functions require PostgreSQL 8.4 ore later.</p> <p>What happens here?</p> <ol> <li>Count in <code>d_ct</code> how many identical sets of <code>(a,b,c)</code> there are in the table with non-null values for <code>d</code>. </li> <li>Pick exactly one row per <code>a</code>. If you don't <code>ORDER BY</code> more than just <code>a</code>, a random row will be picked.</li> <li>In my example I <code>ORDER BY</code> <code>d_ct DESC</code> in addition, so a pseudo-random row out of the set with the highest <code>d_ct</code> will be picked.</li> </ol> <hr> <p>Another, slightly different interpretation of what you might need, with <code>GROUP BY</code>:</p> <pre><code>SELECT DISTINCT ON (a) a, b, c , count(d) AS d_ct , min(e) AS min_e -- aggregate e in some way FROM t GROUP BY a, b, c ORDER BY a, d_ct DESC; </code></pre> <p><code>GROUP BY</code> is applied <em>before</em> <code>DISTINCT ON</code>, so the result is very similar to the one above, only the value for <code>e</code> / <code>min_e</code> is different.</p>