views:

227

answers:

5

So... It is possibile to use a WHERE clause after a HAVING clause?

The first thing that comes to my mind is sub queries, but I'm not sure.

P.S. If the answer is affirmative, could you give some examples?

+3  A: 

A HAVING clause is just a WHERE clause after a GROUP BY. Why not put your WHERE conditions in the HAVING clause?

Nestor
+1 Exactly. The WHERE clause after HAVING is called AND.
Andomar
Conceptually, the HAVING clause is applied after the GROUP BY operation, whereas the WHERE clause is applied before so theoretically there could be optimization by 'filtering' in the WHERE clause. In practice, you will (as always) have to look at how the optimizer handles it e.g. examine the execution plan. Also consider the human reader, who would normally expect to see 'filtering' predicated in the WHERE clause (rather than the join clauses, HAVING clauses, etc).
onedaywhen
+1  A: 

From SELECT help

Processing Order of WHERE, GROUP BY, and HAVING Clauses The following steps show the processing order for a SELECT statement with a WHERE clause, a GROUP BY clause, and a HAVING clause:

The FROM clause returns an initial result set.

The WHERE clause excludes rows not meeting its search condition.

The GROUP BY clause collects the selected rows into one group for each unique value in the GROUP BY clause.

Aggregate functions specified in the select list calculate summary values for each group.

The HAVING clause additionally excludes rows not meeting its search condition.

So, no you can not.

astander
+3  A: 

If it's a trick question, it's possible if the WHERE and the HAVING are not at the same level, as you mentionned, with subquery.

I guess something like that would work

HAVING value=(SELECT max(value) FROM foo WHERE crit=123)

p.s.: why were you asking? Do you have a specific problem?

p.s.s: OK silly me, I missed the "interview*" tag...

pascal
+7  A: 

No, not in the same query.

The where clause goes before the having and the group by. If you want to filter out records before the grouping the condition goes in the where clause, and if you want to filter out grouped records the condition goes in the having clause:

select ...
from ...
where ...
group by ...
having ...

If neither of those are possible to use for some odd reason, you have to make the query a subquery so that you can put the where clause in the outer query:

select ...
from (
   select ...
   from ...
   where ...
   group by ...
   having ...
) x
where ...
Guffa
A: 

Within the same scope, answer is no. If subqueries is allowed then you can avoid using HAVING entirely.

I think HAVING is an anachronism. Hugh Darwen refers to HAVING as "The Folly of Structured Queries":

In old SQL, the WHERE clause could not be used on results of aggregation, so they had to invent HAVING (with same meaning as WHERE):

SELECT D#, AVG(Salary) AS Avg_Sal
  FROM Emp
 GROUP 
    BY D#
HAVING AVG(Salary) > 999;

But would we ever have had HAVING if in 1979 one could write:

SELECT * 
  FROM (
        SELECT D#, AVG(Sal) AS Avg_Sal
          FROM Emp
         GROUP 
            BY D# 
       )
      AS dummy
WHERE Avg_Sal > 999;

I strongly suspect the answer to Darwen's question is no.

onedaywhen