What is the difference between HAVING and WHERE in SQL?
Asked Answered
I

18

288

What is the difference between HAVING and WHERE in an SQL SELECT statement?

EDIT: I have marked Steven's answer as the correct one as it contained the key bit of information on the link:

When GROUP BY is not used, HAVING behaves like a WHERE clause

The situation I had seen the WHERE in did not have GROUP BY and is where my confusion started. Of course, until you know this you can't specify it in the question.

Inversion answered 13/11, 2008 at 16:46 Comment(3)
The line you quote isn't the key bit at all. The key bit, as wcm pointed out, is that HAVING is a post-aggregation filter, whereas WHERE is a pre-aggregation filter.Licorice
this link helped me to understand it better more than all the comments below, thought some one could get help by this codeproject.com/Articles/25258/…Hemiplegia
Also, consider that using HAVING without GROUP BY as a substitute for WHERE is not commonly accepted in all databases such as Oracle.Finial
S
101

HAVING specifies a search condition for a group or an aggregate function used in SELECT statement.

Source

Smetana answered 13/11, 2008 at 16:48 Comment(0)
S
408

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.

Stilliform answered 13/11, 2008 at 16:53 Comment(1)
This should be the accepted answer. The distinction between "having" and "where" makes this immediately clear.Thao
S
101

HAVING specifies a search condition for a group or an aggregate function used in SELECT statement.

Source

Smetana answered 13/11, 2008 at 16:48 Comment(0)
V
30

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.

Varietal answered 28/11, 2011 at 10:15 Comment(2)
Would that be equivalent to "SELECT COUNT( DISTINCT name ) = COUNT( name ) FROM T" ?Profluent
@Profluent Dont know if that works for you, but it does not work on SQL server 2005 but the first one doesMccauley
D
23

The difference between the two is in the relationship to the GROUP BY clause:

  • WHERE comes before GROUP BY; SQL evaluates the WHERE clause before it groups records.

  • HAVING comes after GROUP BY; SQL evaluates HAVING after it groups records.

select statement diagram

References

Decibel answered 29/8, 2012 at 0:57 Comment(9)
Since GROUP BY and HAVING are both optional, the diagram shows both cases, just follow the arrows.Decibel
Example query from my answer to this question: SELECT 1 AS result FROM T HAVING... - in your diagram I can't get to HAVING without passing through GROUP BY but my perfectly valid and useful query has no GROUP BY. Minor point: you don't have the option to include literal values in the SELECT clause.Varietal
@Varietal Since you know about the implicit GROUP BY, why didn't you mention it? Do you know if this behavior is what you are expecting or not?Decibel
Methinks you are quoting me out of context. The question was about mySQL's apparent deviation from the Standard, all but the last paragraph of my answer describes the Standard behaviour, and the last alludes to " the implicit GROUP BY clause mentioned in other answers." Are you saying your diagram is intended to describe (all) implicit behaviour? Wouldn't it be more useful to stick to just the code you need write to get the desired behaviour?Varietal
...I don't know what behavor you are alluding to in the second link. The desired outcome is that you fix the diagram to show the valid (explicit) path I mentioned. Think about it: the diagram covers a entire query yet the question is only interested in the WHERE->HAVING part, so I think deserves close attention to detail. If you think my answer is wrong then edit it or post a suggested correction in comments.Varietal
@Varietal The second link mentions HAVING condition applied to rows rather than groups. Is that non-standard or standard? Is there always or never or sometimes an implicit GROUP BY? Is this behavior 100% standard compliant, deprecated, an antipattern, implementation dependent, or future proof?Decibel
"HAVING condition applied to rows rather than groups" sounds like wrong thinking to me. IMO the behavior is better stated in the same answer: "The having clause excludes rows from the final results that do not meet its search conditions", simple as that, 100% standard compliant. If there is no GROUP BY then there's no implicit grouping. But I'm still slightly confused as to how this relates to your diagram is missing a valid path.Varietal
Quick proof: CREATE TABLE T (c CHAR(1)); INSERT INTO T VALUES ('a'),('a'); SELECT 'true' FROM T HAVING COUNT (c) = 2; should be single row single column result showing true because the search condition removes no rows i.e. has not applied an implicit group by (if it had the grouped then COUNT(c) would be 1, the search condition would fail i.e. a zero row result).Varietal
A misleading syntax diagram does not tell the questioner the semantic (rather than the syntactic) difference between the twain.Aparicio
X
22

The HAVING clause was added to SQL because the WHERE keyword could not be used with aggregate functions.

Check out this w3schools link for more information

Syntax:

SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name
HAVING aggregate_function(column_name) operator value

A query such as this:

SELECT column_name, COUNT( column_name ) AS column_name_tally
  FROM table_name
 WHERE column_name < 3
 GROUP 
    BY column_name
HAVING COUNT( column_name ) >= 3;

...may be rewritten using a derived table (and omitting the HAVING) like this:

SELECT column_name, column_name_tally
  FROM (
        SELECT column_name, COUNT(column_name) AS column_name_tally
          FROM table_name
         WHERE column_name < 3
         GROUP 
            BY column_name
       ) pointless_range_variable_required_here
 WHERE column_name_tally >= 3;
Xanthe answered 13/11, 2008 at 16:47 Comment(1)
You've slightly missed the point: HAVING was added because derived tables hadn't been added to the language and until they were SQL was not relationally complete and once they inevitably were HAVING became redundant.Varietal
R
12

HAVING is used when you are using an aggregate such as GROUP BY.

SELECT edc_country, COUNT(*)
FROM Ed_Centers
GROUP BY edc_country
HAVING COUNT(*) > 1
ORDER BY edc_country;
Rafaello answered 13/11, 2008 at 16:47 Comment(0)
N
8

WHERE is applied as a limitation on the set returned by SQL; it uses SQL's built-in set oeprations and indexes and therefore is the fastest way to filter result sets. Always use WHERE whenever possible.

HAVING is necessary for some aggregate filters. It filters the query AFTER sql has retrieved, assembled, and sorted the results. Therefore, it is much slower than WHERE and should be avoided except in those situations that require it.

SQL Server will let you get away with using HAVING even when WHERE would be much faster. Don't do it.

Newmark answered 13/11, 2008 at 16:53 Comment(2)
Support for derived tables in the SQL language means your assertion "HAVING is necessary for some aggregate filters" is false.Varietal
That's a good point. In the three years since I wrote this answer I've certainly migrated toward using derived tables where I would formerly have used HAVING. I haven't thought through the question of whether HAVING still has some use cases that make sense. I also don't know whether a derived table will universally perform better than HAVING.Newmark
O
8

WHERE clause does not work for aggregate functions
means : you should not use like this bonus : table name

SELECT name  
FROM bonus  
GROUP BY name  
WHERE sum(salary) > 200  

HERE Instead of using WHERE clause you have to use HAVING..

without using GROUP BY clause, HAVING clause just works as WHERE clause

SELECT name  
FROM bonus  
GROUP BY name  
HAVING sum(salary) > 200  
Oleg answered 17/3, 2016 at 12:49 Comment(1)
This is a very important point that is missed in the accepted answer and the answer with the highest votes!Canadianism
B
4

Difference b/w WHERE and HAVING clause:

The main difference between WHERE and HAVING clause is, WHERE is used for row operations and HAVING is used for column operations.

Why we need HAVING clause?

As we know, aggregate functions can only be performed on columns, so we can not use aggregate functions in WHERE clause. Therefore, we use aggregate functions in HAVING clause.

Brachy answered 31/12, 2016 at 5:17 Comment(0)
E
2

One way to think of it is that the having clause is an additional filter to the where clause.

A WHERE clause is used filters records from a result. The filter occurs before any groupings are made. A HAVING clause is used to filter values from a group

Embree answered 31/12, 2016 at 5:6 Comment(0)
R
1

In an Aggregate query, (Any query Where an aggregate function is used) Predicates in a where clause are evaluated before the aggregated intermediate result set is generated,

Predicates in a Having clause are applied to the aggregate result set AFTER it has been generated. That's why predicate conditions on aggregate values must be placed in Having clause, not in the Where clause, and why you can use aliases defined in the Select clause in a Having Clause, but not in a Where Clause.

Remontant answered 13/11, 2008 at 16:56 Comment(0)
S
1

I had a problem and found out another difference between WHERE and HAVING. It does not act the same way on indexed columns.

WHERE my_indexed_row = 123 will show rows and automatically perform a "ORDER ASC" on other indexed rows.

HAVING my_indexed_row = 123 shows everything from the oldest "inserted" row to the newest one, no ordering.

Scurrility answered 9/3, 2011 at 16:50 Comment(2)
How do you know that this is a defined difference between the twain, rather than an accident of implementation of the particular SQL server you were using?Aparicio
I just tested it on MariaDB. I guess it was the SQL server I was using 8 years ago that produced different results.Scurrility
C
1

When GROUP BY is not used, the WHERE and HAVING clauses are essentially equivalent.

However, when GROUP BY is used:

  • The WHERE clause is used to filter records from a result. The filtering occurs before any groupings are made.
  • The HAVING clause is used to filter values from a group (i.e., to check conditions after aggregation into groups has been performed).

Resource from Here

Caresa answered 2/10, 2016 at 20:9 Comment(1)
having and where are not essentially equivalent . it will give error while execution . is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.Larvicide
T
0

From here.

the SQL standard requires that HAVING must reference only columns in the GROUP BY clause or columns used in aggregate functions

as opposed to the WHERE clause which is applied to database rows

Tungstic answered 13/11, 2008 at 16:50 Comment(2)
Source says, "Use of column positions is deprecated because the syntax has been removed from the SQL standard." Sadly, this is wrong: nothing is ever removed from the Standard, which ironically is why we still have HAVING decades after it was 'deprecated' by derived tables.Varietal
Slightly pedantic but quote is not correct e.g. consider SELECT 1 FROM T HAVING COUNT(*) >= 1; - does not reference columns in the GROUP BY clause (there is none) nor columns in aggregate functions (query references no columns at all).Varietal
C
0

While working on a project, this was also my question. As stated above, the HAVING checks the condition on the query result already found. But WHERE is for checking condition while query runs.

Let me give an example to illustrate this. Suppose you have a database table like this.

usertable{ int userid, date datefield, int dailyincome }

Suppose, the following rows are in table:

1, 2011-05-20, 100

1, 2011-05-21, 50

1, 2011-05-30, 10

2, 2011-05-30, 10

2, 2011-05-20, 20

Now, we want to get the userids and sum(dailyincome) whose sum(dailyincome)>100

If we write:

SELECT userid, sum(dailyincome) FROM usertable WHERE sum(dailyincome)>100 GROUP BY userid

This will be an error. The correct query would be:

SELECT userid, sum(dailyincome) FROM usertable GROUP BY userid HAVING sum(dailyincome)>100

Cardinal answered 6/6, 2012 at 10:26 Comment(0)
L
0

WHERE clause is used for comparing values in the base table, whereas the HAVING clause can be used for filtering the results of aggregate functions in the result set of the query Click here!

Lamont answered 29/1, 2013 at 10:33 Comment(0)
J
0

When GROUP BY is not used, the WHERE and HAVING clauses are essentially equivalent.

However, when GROUP BY is used:

  • The WHERE clause is used to filter records from a result. The filtering occurs before any groupings are made.
  • The HAVING clause is used to filter values from a group (i.e., to check conditions after aggregation into groups has been performed).
Jeroboam answered 23/6, 2020 at 14:47 Comment(0)
C
-1

I use HAVING for constraining a query based on the results of an aggregate function. E.G. select * in blahblahblah group by SOMETHING having count(SOMETHING)>0

Conventionalize answered 13/11, 2008 at 16:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.