为什么 MAX 总是 returns 一行?
Why MAX always returns a row?
当 运行 SELECT MAX(col) FROM MY_TABLE
我仍然得到一行 NULL
值,即使 MY_TABLE
中没有记录。与 SELECT col FROM MY_TABLE
相比,我会得到零行,为什么 MAX
会那样?无论如何,还有更多像 MAX
和 return 这样的行吗?它们叫什么?除了使用 MAX
,是否还有另一个示例,即使 WHERE
子句中的条件不满足(或当table 没有记录)?
why MAX behaves like that
因为文档 MAX (Transact-SQL) - Remarks 就是这么说的:
Remarks
MAX ignores any null values.
MAX returns NULL when there is no row to select.
For character columns, MAX finds the highest value in the collating sequence.
MAX is a deterministic function when used without the OVER and ORDER BY clauses. It is nondeterministic when specified with the OVER and ORDER BY clauses. For more information, see Deterministic and Nondeterministic Functions.
强调我的。
我并不是要回答为什么返回带有 NULL 的行是正确的方法。毕竟,SQL 中的 NULL 本身就是一个非常糟糕的主意,criticised by both Codd and Date。这试图解释为什么找到关于 Why
的答案很困难,而且可能不令人满意
更新
计算机历史博物馆收集了可以回答这个问题的访谈。 There are interviews from Date, Chamberlin, Stonebraker 等等。我会开始在那里寻找答案——这绝对比试图寻找论文更有趣。
为什么?一切都开始了....
很难回答why
,而且可能根本没有合乎逻辑的解释。可能有数百篇学术论文、会议出版物和 ANSI SQL 设计委员会会议讨论如何处理空集的分析操作。
也可能只是运气不好。也许是 IBM 的销售经理决定在数据库之上放置一种古怪的语言,而不考虑后果。哪个......它可能是。
SQL 是与关系模型无关的古怪语言。 IBM 的某个业务组为业务人员创建了一种查询语言,同时另一个组开发了关系模型和第一个关系数据库。然后一些产品经理决定将这两种产品结合起来,并将 SQL 置于关系数据库之上,尽管 CJ Date 的 object 离子和开发关系模型的团队的其他成员。
当时还有另一种设计良好的查询语言,QUEL created by Michael StoneBraker,Ingres 和 PostgresQL 的创造者,以及等于 CJ Date 的数据传奇。该语言从一开始就建立在关系模型之上。不幸的是,Ingres 不是很可靠(如果你没有正确关闭,你可能会丢失数据)并且失败了,尽管有一段时间它比 Oracle 更大。
等等,情况变得更糟
在某些时候,SQL 委员会中的一些 IBM 员工实际上试图标准化相等比较中的特定顺序:number = field
,例如 3 = Id
。这将使编写 SQL 解析器变得更容易,因为没有办法将其与赋值混淆。 C 和 C++ 开发人员可能认识到这种模式。不用说,委员会中的 IBM 研究人员并不高兴。
所以我们现在的行为可能来自供应商的实施困难,导致标准妥协。
我怎么知道的?
我很幸运能够参加讲座 by one of them, Hugh Darwen. CJ Date and Hugh Darwen even published The Third Manifesto 关于那些怪癖和协调 object 数据库和 relational-through-SQL 数据库的问题。
我们今天仍然面临的问题再次出现,整个行业都走错了路。想一想尝试将 JOIN 与 EF Core
结合使用的人们提出的所有 SO 问题
您所看到的称为聚合。 MAX
是一种聚合函数,MIN
、SUM
、COUNT
、AVG
等也是。聚合函数只生成一个结果行,除非您指定GROUP BY
子句或 HAVING
子句。
A GROUP BY
产生一行或多行,正如它所说的“根据 ___ 给我一个聚合结果”,例如“给我每个部门的员工人数和最高薪水”这将导致每个部门一行。
HAVING
子句类似于聚合结果上的 WHERE
子句。例如,在给定的示例中,您可以添加“但仅适用于至少有 10 名员工的部门”。
因此,如果在 col 中没有值(即不存在最大值)的情况下不需要结果行,请添加 HAVING
子句:
SELECT MAX(col) FROM my_table HAVING MAX(col) IS NOT NULL;
这是 SQL 服务器关于聚合函数的文档:https://docs.microsoft.com/de-de/sql/t-sql/functions/aggregate-functions-transact-sql?view=sql-server-ver15
编辑:
至于在没有数据匹配WHERE
子句的情况下是否存在return空值而不是无行的意思:WHERE
子句从结果中删除行,所以我们必须想办法解决这个问题。一种是外连接,一种是联合查询,可能还有其他方法。
一个例子:
select dept_id, dept_name from departments where boss = 'Mr. X';
会return没有一行,如果没有任何部门的老板是X先生。
但是在外部连接表时我们得到空行:
select d.dept_id, d.dept_name
from (select 1) dummy
left outer join departments d on boss = 'Mr. X';
或者我们合并两个查询,一个用于匹配,一个用于不匹配:
select dept_id, dept_name from departments where boss = 'Mr. X'
union all
select null, null where not exists (select * from departments where boss = 'Mr. X');
当 运行 SELECT MAX(col) FROM MY_TABLE
我仍然得到一行 NULL
值,即使 MY_TABLE
中没有记录。与 SELECT col FROM MY_TABLE
相比,我会得到零行,为什么 MAX
会那样?无论如何,还有更多像 MAX
和 return 这样的行吗?它们叫什么?除了使用 MAX
,是否还有另一个示例,即使 WHERE
子句中的条件不满足(或当table 没有记录)?
why MAX behaves like that
因为文档 MAX (Transact-SQL) - Remarks 就是这么说的:
Remarks
MAX ignores any null values.
MAX returns NULL when there is no row to select.
For character columns, MAX finds the highest value in the collating sequence.
MAX is a deterministic function when used without the OVER and ORDER BY clauses. It is nondeterministic when specified with the OVER and ORDER BY clauses. For more information, see Deterministic and Nondeterministic Functions.
强调我的。
我并不是要回答为什么返回带有 NULL 的行是正确的方法。毕竟,SQL 中的 NULL 本身就是一个非常糟糕的主意,criticised by both Codd and Date。这试图解释为什么找到关于 Why
的答案很困难,而且可能不令人满意
更新
计算机历史博物馆收集了可以回答这个问题的访谈。 There are interviews from Date, Chamberlin, Stonebraker 等等。我会开始在那里寻找答案——这绝对比试图寻找论文更有趣。
为什么?一切都开始了....
很难回答why
,而且可能根本没有合乎逻辑的解释。可能有数百篇学术论文、会议出版物和 ANSI SQL 设计委员会会议讨论如何处理空集的分析操作。
也可能只是运气不好。也许是 IBM 的销售经理决定在数据库之上放置一种古怪的语言,而不考虑后果。哪个......它可能是。
SQL 是与关系模型无关的古怪语言。 IBM 的某个业务组为业务人员创建了一种查询语言,同时另一个组开发了关系模型和第一个关系数据库。然后一些产品经理决定将这两种产品结合起来,并将 SQL 置于关系数据库之上,尽管 CJ Date 的 object 离子和开发关系模型的团队的其他成员。
当时还有另一种设计良好的查询语言,QUEL created by Michael StoneBraker,Ingres 和 PostgresQL 的创造者,以及等于 CJ Date 的数据传奇。该语言从一开始就建立在关系模型之上。不幸的是,Ingres 不是很可靠(如果你没有正确关闭,你可能会丢失数据)并且失败了,尽管有一段时间它比 Oracle 更大。
等等,情况变得更糟
在某些时候,SQL 委员会中的一些 IBM 员工实际上试图标准化相等比较中的特定顺序:number = field
,例如 3 = Id
。这将使编写 SQL 解析器变得更容易,因为没有办法将其与赋值混淆。 C 和 C++ 开发人员可能认识到这种模式。不用说,委员会中的 IBM 研究人员并不高兴。
所以我们现在的行为可能来自供应商的实施困难,导致标准妥协。
我怎么知道的?
我很幸运能够参加讲座 by one of them, Hugh Darwen. CJ Date and Hugh Darwen even published The Third Manifesto 关于那些怪癖和协调 object 数据库和 relational-through-SQL 数据库的问题。
我们今天仍然面临的问题再次出现,整个行业都走错了路。想一想尝试将 JOIN 与 EF Core
结合使用的人们提出的所有 SO 问题您所看到的称为聚合。 MAX
是一种聚合函数,MIN
、SUM
、COUNT
、AVG
等也是。聚合函数只生成一个结果行,除非您指定GROUP BY
子句或 HAVING
子句。
A GROUP BY
产生一行或多行,正如它所说的“根据 ___ 给我一个聚合结果”,例如“给我每个部门的员工人数和最高薪水”这将导致每个部门一行。
HAVING
子句类似于聚合结果上的 WHERE
子句。例如,在给定的示例中,您可以添加“但仅适用于至少有 10 名员工的部门”。
因此,如果在 col 中没有值(即不存在最大值)的情况下不需要结果行,请添加 HAVING
子句:
SELECT MAX(col) FROM my_table HAVING MAX(col) IS NOT NULL;
这是 SQL 服务器关于聚合函数的文档:https://docs.microsoft.com/de-de/sql/t-sql/functions/aggregate-functions-transact-sql?view=sql-server-ver15
编辑:
至于在没有数据匹配WHERE
子句的情况下是否存在return空值而不是无行的意思:WHERE
子句从结果中删除行,所以我们必须想办法解决这个问题。一种是外连接,一种是联合查询,可能还有其他方法。
一个例子:
select dept_id, dept_name from departments where boss = 'Mr. X';
会return没有一行,如果没有任何部门的老板是X先生。
但是在外部连接表时我们得到空行:
select d.dept_id, d.dept_name
from (select 1) dummy
left outer join departments d on boss = 'Mr. X';
或者我们合并两个查询,一个用于匹配,一个用于不匹配:
select dept_id, dept_name from departments where boss = 'Mr. X'
union all
select null, null where not exists (select * from departments where boss = 'Mr. X');