HAVING子句如何真正起作用?

时间:2015-10-30 07:40:20

标签: mysql sql oracle postgresql having-clause

我们能够在SQL查询中使用HAVING子句来过滤行组。当我们使用GROUP BY子句时,它以这种方式直接工作。

但是,让我们来看看这个问题:

select 1 where 1!=1 having count(*)=0;

(或者将其附加到'来自双重'对于Oracle)。

如果HAVING真的进行了群组过滤,那么在WHERE之后我们没有任何行,所以我们没有任何群组,结果必须是“没有选择行”#。

但是在PostgreSQL,MySQL和Oracle中我们得到了' 1'作为查询的结果。

问题:HAVING如何真正起作用?

SQL小提琴测试:http://www.sqlfiddle.com/#!15/d5407/51

2 个答案:

答案 0 :(得分:7)

如果没有GROUP BY聚合总是返回一行,那么COUNT(*)会返回0

此列不在您的选择列表中,而是在硬编码的文字1

select count(*) where 1!=1 ;
select 'bla' where 1!=1 having count(*)=0;

请参阅fiddle

答案 1 :(得分:3)

没有HAVING cluase的

GROUP BY有效且可在整个表格上运行。从SQL标准92:

  

7.10

     

:: = HAVING

     

语法规则

     

1)让HC成为。设TE应立即包含HC。

     

如果TE不立即包含a,则GROUP BY()是隐式的。

  

:: =       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;