We able to use HAVING clause in SQL-query to filtrate groups of row. When we use GROUP BY clause it work directly in this way.
But, let's look to this query:
select 1 where 1!=1 having count(*)=0;
(or append it with 'from dual' for Oracle).
If HAVING really do group filtration, after WHERE we have no any rows, so we have no any group and result must be 'No row selected'.
But in PostgreSQL, MySQL and Oracle we get '1' as result of query.
Question: how does HAVING really work?
SQL Fiddle for test: http://www.sqlfiddle.com/#!15/d5407/51
The HAVING clause specifies the condition or conditions for a group or an aggregation. The employee table below helps us analyze the HAVING clause. It contains employee IDs (the emp_id column), the department where that employee works, and the employee's salary .
The HAVING Clause enables you to specify conditions that filter which group results appear in the results. The WHERE clause places conditions on the selected columns, whereas the HAVING clause places conditions on groups created by the GROUP BY clause.
Well, the main distinction between the two clauses is that HAVING can be applied for subsets of aggregated groups, while in the WHERE block, this is forbidden. In simpler words, after HAVING, we can have a condition with an aggregate function, while WHERE cannot use aggregate functions within its conditions.
A HAVING clause in SQL specifies that an SQL SELECT statement must only return rows where aggregate values meet the specified conditions.
If there's no GROUP BY
an aggregate always returns a row, in your case the COUNT(*)
returns 0
.
This column is not in your Select list, but the hard-coded literal 1
select count(*) where 1!=1 ;
select 'bla' where 1!=1 having count(*)=0;
See fiddle
HAVING
without GROUP BY
cluase is valid and operates on entire table. From SQL Standard 92:
7.10
::= HAVING
Syntax Rules
1) Let HC be the . Let TE be the that immediately contains HC.
If TE does not immediately contain a , then GROUP BY ( ) is implicit.
and:
::= GROUP BY
<grouping specification> ::= <grouping column reference> | <rollup list> | <cube list> | <grouping sets list> | <grand total> | <concatenated grouping> <grouping set> ::= <ordinary grouping set> | <rollup list> | <cube list> | <grand total> <grand total> ::= <left paren> <right paren>
As you see GROUP BY ()
is treated as grand total
.
In your example you have:
select 1
where 1!=1
having count(*)=0;
is actually something like:
select 1
where 1!=1
-- group by ()
having count(*)=0;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With