Grouping Rows with GROUP BY

HAVING

When Oracle processes a GROUP BY query the WHERE clause is applied to the result set before the rows are grouped together. This allows us to use WHERE conditions involving columns like GRP_B in the query below, which is not listed in the GROUP BY clause.

select grp_a, count(*)
from   t
WHERE  GRP_B in ( 'b2', 'b3' )
group by grp_a
order by grp_a ;
 
GRP_A        COUNT(*)
---------- ----------
a1                  3
a2                  3
 

Thia does, however, prevent us from using conditions that involve aggregate values like COUNT(*) that are calculated after the GROUP BY clause is applied. For example, the following will not work.

select grp_a, count(*)
from   t
WHERE  COUNT(*) > 4
group by grp_a
order by grp_a ;
WHERE  COUNT(*) > 4
       *
ERROR at line 3:
ORA-00934: group function is not allowed here


 

For these types of conditions the HAVING clause can be used.

select grp_a, count(*)
from   t
group by grp_a
HAVING   COUNT(*) > 4
order by grp_a ;
 
GRP_A        COUNT(*)
---------- ----------
a1                  5
 

Note that the HAVING clause cannot reference table columns like VAL that are not listed in the GROUP BY clause.

select grp_a, count(*)
from   t
group by grp_a
HAVING   VAL > 5
order by grp_a ;
HAVING   VAL > 5
         *
ERROR at line 4:
ORA-00979: not a GROUP BY expression


 

It can, on the other hand, reference table columns like GRP_A that are in the GROUP BY clause.

select grp_a, count(*)
from   t
group by grp_a
HAVING   GRP_A = 'a2'
order by grp_a ;
 
GRP_A        COUNT(*)
---------- ----------
a2                  3
 

but doing so yields the same result as using a WHERE clause.

select grp_a, count(*)
from   t
WHERE  GRP_A = 'a2'
group by grp_a
order by grp_a ;
 
GRP_A        COUNT(*)
---------- ----------
a2                  3
 

Given a choice between the last two snippets I expect using a WHERE clause provides the best performance in most, if not all, cases.




Linking to SQL Snippets ™

To link to this page in Oracle Technology Network Forums or OraFAQ Forums cut and paste this code.

  • [url=http://www.sqlsnippets.com/en/topic-13118.html]SQL Snippets: Grouping Rows with GROUP BY - HAVING[/url]

To link to this page in HTML documents or Blogger comments cut and paste this code.

  • <a href="http://www.sqlsnippets.com/en/topic-13118.html">SQL Snippets: Grouping Rows with GROUP BY - HAVING</a>

To link to this page in other web sites use the following values.

  • Link Text : SQL Snippets: Grouping Rows with GROUP BY - HAVING
  • URL (href): http://www.sqlsnippets.com/en/topic-13118.html