【问题标题】:Categorizing a sub-expression within an expression对表达式中的子表达式进行分类
【发布时间】:2021-04-05 16:32:51
【问题描述】:

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

我想所有三个项目都可以称为“操作数”,后两个可以称为“子选择”,但是有没有更好的方法来分类“子选择”只是最终选择表达式的一个组成部分?抱歉,如果这是迂腐的,但我正在寻找一种清晰的方法来对复杂表达式中的“术语”进行分类。

【问题讨论】:

  • (忽略表别名混淆)您有两个相关(您在子查询内部根据外部过滤)标量(返回一行一列)子查询。您将这些标量子查询视为任何其他表达式。
  • @AndrewSayer 当然,但是有没有办法区分一个终端子查询和一个更大的表达式的一部分?也许这只是一个通用的编程术语,而不是一个 sql 术语。
  • 您的意思是作为select 子句的一部分而不是from 子句作为行源?

标签: sql subquery formal-languages operands


【解决方案1】:
4  + (SELECT ...) / (SELECT ...)

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

子查询这个词表示这是整个查询中的一个中间结果。 标量 意味着子查询只返回一行,一列(或者,可能根本没有行 - 但这里不是这种情况)。 标量部分是最重要的概念:如果其中一个子查询返回多于一行(或多于一列),则它不能用作算术运算中的操作数,并且查询错误。

【讨论】:

  • 我明白了,谢谢。有什么方法可以区分作为表达式一部分的 标量子查询 和直接返回值的子查询?一个例子是:SELECT (select ...)SELECT 1+(select ...) 后者在标量子查询返回后涉及一些操作。可能类似于“非终端标量子查询”。
  • @David542:不,我不知道具体的技术术语。
【解决方案2】:

这个子查询可能不符合你的预期:

(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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    • 2015-08-09
    相关资源
    最近更新 更多