Reputation: 25
Are these queries exactly the same, or is it possible to get different results depending on the data?
SELECT A, B, C, D
FROM Table_A
GROUP BY A, B, C, D , E
HAVING A in (1,2) AND E = 1 AND MIN(status) = 100
SELECT A, B, C, D
FROM Table_A
WHERE A IN (1,2) AND E = 1 AND status = 100
GROUP BY A, B, C, D , E
Upvotes: 1
Views: 1526
Reputation: 65363
They're not equal.
When you consider the following block
create table Table_A(A int, B int, C int, D int, E int, status int);
insert into Table_A values(1,1,1,1,1,100);
insert into Table_A values(1,1,1,1,1,10);
insert into Table_A values(2,1,1,1,1,10);
SELECT A, B, C, D, 'First Query' as query
FROM Table_A
GROUP BY A, B, C, D , E
HAVING A in (1,2) AND E = 1 AND MIN(status) = 100;
SELECT A, B, C, D, 'Second Query' as query
FROM Table_A
WHERE A IN (1,2) AND E = 1 AND status = 100
GROUP BY A, B, C, D , E
you get
A B C D query
- - - - -------------
1 1 1 1 Second Query
as a result ( only the second one returns ),
since for both of the groupings 1,1,1,1,1
and 2,1,1,1,1
-> min(status)=10
.
For this reason min(status)=100
case never occurs and first query returns no result.
Upvotes: 1
Reputation: 51
At a high level:
The where clause specifies search conditions for the rows returned by the Query and limits rows to a meaningful set.
The having clause works as a filter on top of grouped rows.
Upvotes: 0
Reputation: 16397
A couple of things:
HAVING MIN(status) = 100
and
WHERE status = 100
are different. The where condition filters out anything that is not 100, period -- it's not even evaluated. The having clause only evaluates it after every record has been read and it looks at the result of the aggregate function (min) for the specified grouping.
Also, a more subtle difference is that the "where" clause for non-aggregate functions is preferable because it can make use of any index on the table, and equally important it will prevent records from being grouped and joined.
For example
having E = 1
and
where E = 1
functionally do the same thing. The difference is you need to collect, group and sort a bunch of records only to discard them using "having," whereas the "where" option removes them before any grouping ever occurs. Also, in this example, with the "where" option, you can remove E from the grouping criteria since it is always 1.
Upvotes: 0