让. HC_ <having clause>让TE是<table expression>立即包含HC。如果TE不立即包含 a
<group by clause>,则GROUP BY ()隐含“ ”。令T为由<group by clause>GBC立即包含在中定义的表的描述符,TE令R为 的结果GBC。
好的,所以很清楚了。
断言:1=1是真实的搜索条件。我不会为此提供任何引用。
现在
SELECT 1 FROM r GROUP BY () HAVING 1=1
相当于
SELECT 1 FROM r GROUP BY ()
引用 ISO/IEC 9075-2:2011 7.10 一般规则 1:
对<search condition>每组 进行评估R。结果是一个分组表,其中包含结果为真的<having clause>那些 R 组
。<search condition>
按照标准:
方法
引用 ISO/IEC 9075-2:2011 7.10 语法规则 1(HAVING 子句定义的一部分):
好的,所以很清楚了。
断言:
1=1
是真实的搜索条件。我不会为此提供任何引用。现在
相当于
引用 ISO/IEC 9075-2:2011 7.10 一般规则 1:
逻辑:由于查找条件始终为真,结果为
R
,即group by表达式的结果。以下摘自7.9通则(GROUP BY CLAUSE的定义)
因此我们可以得出结论
生成一个分组表,由一组组成,行数为零(因为 R 为空)。
摘自 7.12 的一般规则,它定义了查询规范(也称为 SELECT 语句):
因此,由于表有一组,它必须有一个结果行。
因此
应该返回 1 行结果集。
QED
当有
HAVING
子句时,没有WHERE
子句时:...然后
GROUP BY ()
是隐含的。所以,查询应该等同于:...应该将表格的所有行分组为一组(即使表格根本没有行 - 它仍然是一组 0 行)并返回 1 行。在那之后,
HAVING
带有True
条件的应该完全没有效果。从另一个角度来看,像这样的查询应该返回多少行?
一、零或“零或一,取决于表是否为空”?
我觉得一排,不管有多少排
r
都有。据我所见,SQLServer 和 PostgerSQL 似乎根本不费心查看表:
也只返回一行。尽管SQLServer 文档说
在这种情况下这是不正确的 -
WHERE 1=1
而不是HAVING
返回正确的行数。我会说这是优化器错误(或者至少是文档错误)... SQLServer 计划在以下情况下显示“持续扫描”HAVING
和“表扫描”WHERE
...Oracle 和 Mysql 的行为对我来说似乎更符合逻辑和正确......