我们能够在SQL查询中使用HAVING子句来过滤行组。当我们使用GROUP BY子句时,它以这种方式直接工作。
但是,让我们来看看这个问题:
select 1 where 1!=1 having count(*)=0;
(或者将其附加到'来自双重'对于Oracle)。
如果HAVING真的进行了群组过滤,那么在WHERE之后我们没有任何行,所以我们没有任何群组,结果必须是“没有选择行”#。
但是在PostgreSQL,MySQL和Oracle中我们得到了' 1'作为查询的结果。
问题:HAVING如何真正起作用?
答案 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;