Обсуждение: GROUP BY / HAVING - am I being thick?

Поиск
Список
Период
Сортировка

GROUP BY / HAVING - am I being thick?

От
"Andrew C.R. Martin"
Дата:
I have a question about GROUP BY / HAVING. It seems I can't do
something I *think* I should be able to do!


Give the following table called 'summary':
------------------------
(int)   (bool) (int)
codon   expl   nexamples
------------------------286     t        1286     f        1286     f        4286     t       13286     t       37286
 t        1287     f        3287     f        3287     f        4287     f        1288     f        2288     f
3288    f        4288     f        2289     f        1289     t        3
 
------------------------

For each codon number, I want to obtain sum(nexamples) where expl = 'f';

i.e. I want to get the result:
------------------------
(int)   (int)
codon   sum
------------------------286     5287     11288     11289     1
------------------------

I can do this using a temporary table (or equally using a view):       SELECT codon, nexamples INTO summary_tmp
FROMsummary       WHERE expl = 'f';       SELECT codon, sum(nexamples)       FROM summary_tmp       GROUP BY codon;
 DROP TABLE summary_tmp; 
 
but I thought I should be able to do it using GROUP BY and HAVING.
The following looks as though it should work according to "The
Practical SQL Handbook" (Bowman, Emerson & Darnovsky)

SELECT codon, sum(nexamples)
FROM summary
WHERE expl = 'f'
GROUP BY codon
HAVING expl = 'f';

I've tried various contortions of putting expl in the SELECT clause
and in the GROUP BY clause, but nothing seems to work. The docs say that
PostgreSQL requires the HAVING clause "unambiguously reference a grouping
column" whatever that means - I tried putting expl in the GROUP BY, but it
didn't help.


Any suggestions gratefully received!


Thanks,

Andrew



--
Dr. Andrew C.R. Martin          EMail:  a.c.r.martin@reading.ac.uk  (work)
Lecturer in Bioinformatics              andrew@stagleys.demon.co.uk (home)
University of Reading
Tel.: +44 (0)118 987 5123x7022  Fax:    +44 (0)118 931 0180


Re: GROUP BY / HAVING - am I being thick?

От
Tom Lane
Дата:
"Andrew C.R. Martin" <a.c.r.martin@reading.ac.uk> writes:
> For each codon number, I want to obtain sum(nexamples) where expl = 'f';

> The following looks as though it should work according to "The
> Practical SQL Handbook" (Bowman, Emerson & Darnovsky)

> SELECT codon, sum(nexamples)
> FROM summary
> WHERE expl = 'f'
> GROUP BY codon
> HAVING expl = 'f';

Just drop the HAVING clause and that will work --- you're already
filtering by expl at the WHERE stage, so there's no need to do it
again after grouping (quite aside from the fact that you can't
reference an ungrouped column in HAVING).

The thing to remember about WHERE vs HAVING is that WHERE filters tuples
before they are aggregated into groups, while HAVING filters afterwards.
Whatever tuples get past the WHERE filter are collected into groups,
and then HAVING is applied to the per-group output tuples to filter out
whole groups that you don't want.

In practice, you only need HAVING if you want to filter on aggregate
functions of the groups.  For instance, if in your example you didn't
want to hear about codons with sum(nexamples) < 100, you'd do

SELECT codon, sum(nexamples)
FROM summary
WHERE expl = 'f'
GROUP BY codon
HAVING sum(nexamples) >= 100;

Once you realize that HAVING applies post-group, it should be pretty
clear why the HAVING clause can only reference group-column values
and aggregate results.  Anything else is not well-defined at the
group level.  For instance, the group for codon=286 has several
different values for nexamples, so you can't ask about a specific
value of nexamples in the HAVING clause --- which one would you get?
        regards, tom lane


Re: GROUP BY / HAVING - am I being thick?

От
"Andrew C.R. Martin"
Дата:

> I have a question about GROUP BY / HAVING. It seems I can't do
> something I *think* I should be able to do!
[...]
> SELECT codon, sum(nexamples)
> FROM summary
> WHERE expl = 'f'
> GROUP BY codon
> HAVING expl = 'f';

OK! As I thought, I was being thick - helps to read the book properly instead
of dipping into it. Thanks Tom for clearing this up!


Andrew

--
Dr. Andrew C.R. Martin          EMail:  a.c.r.martin@reading.ac.uk  (work)
Lecturer in Bioinformatics              andrew@stagleys.demon.co.uk (home)
University of Reading
Tel.: +44 (0)118 987 5123x7022  Fax:    +44 (0)118 931 0180