问题描述
假设我有以下 select_expr
:
SELECT
name,4 + (
(SELECT SUM(revenue) FROM tbl WHERE name=tbl.name)
/ (SELECT COUNT(revenue) FROM tbl WHERE name=tbl.name)
)
FROM tbl
忽略这个查询没有意义的事实,我很好奇第二个 select_expr
将如何分类:
4 + (SELECT ...) / (SELECT ...)
我想所有三个项目都可以称为“操作数”,后两个项目可以称为“子选择”,但是有没有更好的方法来分类“子选择”只是最终选择表达式的一个组成部分?抱歉,如果这有点迂腐,但我正在寻找一种清晰的方法来对复杂表达式中的“术语”进行分类。
解决方法
4 + (SELECT ...) / (SELECT ...)
您有一个涉及三个操作数的算术运算。第一个操作数是一个常量,另外两个是标量子查询。
术语 subquery 表示这是整个查询的中间结果。 scalar 意味着子查询只返回一行,一列(或者,可能根本没有行——但这里不是这种情况)。 scalar 部分是最重要的概念:如果其中一个子查询返回多于一行(或多于一列),则它不能用作算术运算中的操作数,并且查询错误。
,这个子查询可能不符合你的预期:
(SELECT SUM(revenue) FROM tbl WHERE name = tbl.name)
解释为:
(SELECT SUM(revenue) FROM tbl WHERE tbl.name = tbl.name)
始终限定查询中包含多个表引用的所有列引用!。这对于相关子查询尤其重要。
其中(假设 name
从不NULL
)与以下内容相同:
(SELECT SUM(revenue) FROM tbl)
所以,这是一个标量子查询的例子。即,返回一个值且最多返回一行的子查询。
您可能希望这是一个标量相关子查询。这将是一个标量子查询,它具有连接到外部表的条件。表示为:
(SELECT SUM(revenue) FROM tbl tbl2 WHERE tbl2.name = tbl.name)
但是,我根本不建议为此目的使用子查询。只需使用窗口函数:
SUM(revenue) OVER (PARTITION BY name)