HAVING 子句如何真正起作用?
How does the HAVING clause really work?
我们可以在 SQL-query 中使用 HAVING 子句来过滤行组。当我们使用 GROUP BY 子句时,它直接以这种方式工作。
但是,让我们看看这个查询:
select 1 where 1!=1 having count(*)=0;
(或为 Oracle 添加 'from dual')。
如果HAVING真的进行分组过滤,WHERE之后我们没有任何行,所以我们没有任何分组,结果必须是'No row selected'。
但在 PostgreSQL、MySQL 和 Oracle 中,我们得到“1”作为查询结果。
问题:HAVING 到底是如何工作的?
SQL Fiddle 测试:http://www.sqlfiddle.com/#!15/d5407/51
没有 GROUP BY
子句的 HAVING
是有效的并且在整个 table 上运行。来自 SQL 标准 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.
和:
::=
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>
如您所见,GROUP BY ()
被视为 grand total
。
在你的例子中你有:
select 1
where 1!=1
having count(*)=0;
实际上是这样的:
select 1
where 1!=1
-- group by ()
having count(*)=0;
如果没有 GROUP BY
聚合总是 returns 一行,在你的情况下 COUNT(*)
returns 0
.
此列不在您的 Select 列表中,而是硬编码文字 1
select count(*) where 1!=1 ;
select 'bla' where 1!=1 having count(*)=0;
我们可以在 SQL-query 中使用 HAVING 子句来过滤行组。当我们使用 GROUP BY 子句时,它直接以这种方式工作。
但是,让我们看看这个查询:
select 1 where 1!=1 having count(*)=0;
(或为 Oracle 添加 'from dual')。
如果HAVING真的进行分组过滤,WHERE之后我们没有任何行,所以我们没有任何分组,结果必须是'No row selected'。
但在 PostgreSQL、MySQL 和 Oracle 中,我们得到“1”作为查询结果。
问题:HAVING 到底是如何工作的?
SQL Fiddle 测试:http://www.sqlfiddle.com/#!15/d5407/51
GROUP BY
子句的 HAVING
是有效的并且在整个 table 上运行。来自 SQL 标准 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.
和:
::= 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>
如您所见,GROUP BY ()
被视为 grand total
。
在你的例子中你有:
select 1
where 1!=1
having count(*)=0;
实际上是这样的:
select 1
where 1!=1
-- group by ()
having count(*)=0;
如果没有 GROUP BY
聚合总是 returns 一行,在你的情况下 COUNT(*)
returns 0
.
此列不在您的 Select 列表中,而是硬编码文字 1
select count(*) where 1!=1 ;
select 'bla' where 1!=1 having count(*)=0;