对表达式中的子表达式进行分类

问题描述

假设我有以下 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)