What is the difference between HAVING and WHERE in SQL?
HAVING specifies a search condition for a group or an aggregate function used in SELECT statement.
Source
HAVING: is used to check conditions after the aggregation takes place.
WHERE: is used to check conditions before the aggregation takes place.
This code:
select City, CNT=Count(1)
From Address
Where State = 'MA'
Group By City
Gives you a table of all cities in MA and the number of addresses in each city.
This code:
select City, CNT=Count(1)
From Address
Where State = 'MA'
Group By City
Having Count(1)>5
Gives you a table of cities in MA with more than 5 addresses and the number of addresses in each city.
Number one difference for me: if HAVING
was removed from the SQL language then life would go on more or less as before. Certainly, a minority queries would need to be rewritten using a derived table, CTE, etc but they would arguably be easier to understand and maintain as a result. Maybe vendors' optimizer code would need to be rewritten to account for this, again an opportunity for improvement within the industry.
Now consider for a moment removing WHERE
from the language. This time the majority of queries in existence would need to be rewritten without an obvious alternative construct. Coders would have to get creative e.g. inner join to a table known to contain exactly one row (e.g. DUAL
in Oracle) using the ON
clause to simulate the prior WHERE
clause. Such constructions would be contrived; it would be obvious there was something was missing from the language and the situation would be worse as a result.
TL;DR we could lose HAVING
tomorrow and things would be no worse, possibly better, but the same cannot be said of WHERE
.
From the answers here, it seems that many folk don't realize that a HAVING
clause may be used without a GROUP BY
clause. In this case, the HAVING
clause is applied to the entire table expression and requires that only constants appear in the SELECT
clause. Typically the HAVING
clause will involve aggregates.
This is more useful than it sounds. For example, consider this query to test whether the name
column is unique for all values in T
:
SELECT 1 AS result
FROM T
HAVING COUNT( DISTINCT name ) = COUNT( name );
There are only two possible results: if the HAVING
clause is true then the result with be a single row containing the value 1
, otherwise the result will be the empty set.