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

Categorizing a sub-expression within an expression

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

我想所有三个项目都可以称为 'operands',后两个可以称为 'sub-selects',但是有没有更好的方法来分类“subselect”是只是最终 select 表达式的一个组成部分?抱歉,如果这有点迂腐,但我正在寻找一种清晰的方法来在复杂表达式中对 'terms' 进行分类。

4  + (SELECT ...) / (SELECT ...)

您有一个涉及三个操作数的算术运算。第一个操作数是常量,另外两个是标量子查询.

术语子查询表示这是整个查询的中间结果。 scalar 意味着子查询 returns 只有一行,一列(或者,可能根本没有行——但这里不是这种情况)。 标量部分是最重要的概念:如果子查询之一returns超过一行(或超过一列),那么它不能用作操作数算术运算和查询错误。

这个子查询可能没有达到您的预期:

(SELECT SUM(revenue) FROM tbl WHERE name = tbl.name)

解释为:

(SELECT SUM(revenue) FROM tbl WHERE tbl.name = tbl.name)

始终限定具有多个 table 引用的查询中的所有列引用!。这对于相关子查询尤为重要。

其中(假设 name 永远不会 NULL)与:

相同
(SELECT SUM(revenue) FROM tbl)

因此,这是一个 标量子查询 的示例。即 returns 一个值且最多一行的子查询。

可能打算将其作为标量相关子查询。那将是一个 标量子查询 ,它有一个连接到外部 table 的条件。表示为:

(SELECT SUM(revenue) FROM tbl tbl2 WHERE tbl2.name = tbl.name)

但是,我完全不建议为此目的使用子查询。只需使用 window 函数:

SUM(revenue) OVER (PARTITION BY name)