Mar*_*ith 20 aggregate sql-standard
我在这里的评论中遇到了这个难题
CREATE TABLE r (b INT);
SELECT 1 FROM r HAVING 1=1;
Run Code Online (Sandbox Code Playgroud)
SQL Server和PostgreSQL返回 1 行。
哪个是正确的?或者两者都同样有效?
Kev*_*art 17
按照标准:
SELECT 1 FROM r HAVING 1=1
Run Code Online (Sandbox Code Playgroud)
方法
SELECT 1 FROM r GROUP BY () HAVING 1=1
Run Code Online (Sandbox Code Playgroud)
引用 ISO/IEC 9075-2:2011 7.10 语法规则 1(HAVING 子句定义的一部分):
让
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
Run Code Online (Sandbox Code Playgroud)
相当于
SELECT 1 FROM r GROUP BY ()
Run Code Online (Sandbox Code Playgroud)
引用 ISO/IEC 9075-2:2011 7.10 一般规则 1:
在
<search condition>对各组的评价R。的结果<having clause>是那些 R 组的分组表,其中 的结果<search condition>为真。
逻辑:由于搜索条件始终为真,结果为R,即group by表达式的结果。
以下摘自 7.9 总则(GROUP BY CLAUSE 的定义)
1) 如果没有
<where clause>指定,那么让T是前面的结果<from clause>;否则, letT是前面的结果<where clause>。2) 案例:
a) 如果没有分组列,则结果
<group by clause>是分组表T作为其唯一的组组成。
因此我们可以得出结论
FROM r GROUP BY ()
Run Code Online (Sandbox Code Playgroud)
结果是一个分组表,由一组组成,行数为零(因为 R 为空)。
7.12 通用规则的摘录,它定义了查询规范(又名 SELECT 语句):
1) 案例:
a) 如果
T不是分组表,则 [...]b) 如果
T是分组表,则案件:
i) 如果
T有 0(零)个组,则令 TEMP 为空表。ii) 如果
T有一个或多个组,则将每个<value expression>组应用于T产生行表TEMP的每个组M,其中M是 中的组数T。iTEMP的-th 列包含通过i-th的评估得出的值<value expression>。[...]2) 案例:
a) 如果
<set quantifier>DISTINCT未指定 ,则 的结果<query specification>为TEMP。
因此,由于表有一组,因此它必须有一个结果行。
因此
SELECT 1 FROM r HAVING 1=1
Run Code Online (Sandbox Code Playgroud)
应该返回 1 行结果集。
QED
有HAVING子句时,无WHERE子句时:
SELECT 1 FROM r HAVING 1=1;
Run Code Online (Sandbox Code Playgroud)
...然后GROUP BY ()是隐含的。因此,查询应等效于:
SELECT 1 FROM r GROUP BY () HAVING 1=1;
Run Code Online (Sandbox Code Playgroud)
...应该将表的所有行分组为一组(即使表根本没有行 - 它仍然是一组 0 行)并返回 1 行。之后HAVINGwithTrue条件应该没有任何影响。
从另一个角度来看,这样的查询应该返回多少行?
SELECT COUNT(*), MAX(b) FROM r;
Run Code Online (Sandbox Code Playgroud)
一,零或“零或一,取决于表是否为空”?
我认为一行,无论有多少行r。