【问题标题】:Confusion about the execution order in SQL querySQL查询中的执行顺序混淆
【发布时间】:2013-08-11 05:27:52
【问题描述】:

我正在使用 Silberschatz、Korth 和 Surdashan 的《数据库系统概念》一书来研究数据库(我引用作者是因为关系代数符号与其他作者不同...

好吧,我认为SQL查询的执行顺序是基于关系代数的,例如:

如果我有这个 SQL 查询:

SELECT nombre_sucursal, AVG(saldo) AS media_sucursal
FROM cuenta
GROUP BY nombre_sucursal
HAVING media_sucursal > 800

对应的关系代数表达式如下:

Π nombre_sucursal (σ saldo > 800 (nombre_sucursal Ģ avg(saldo) (cuenta))

嗯...为此,在我看来,SQL 查询中的执行顺序是(如果您向后看关系代数表达式):

  1. FROM - (cuenta) 关系代数表达式中的基本关系
  2. GROUP BY nombre_sucursal - nombre_sucursal Ģ avg(saldo) 在关系代数表达式中
  3. HAVING media_sucursal > 800 - σ saldo > 800 关系代数表达式中的选择操作
  4. SELECT nombre_sucursal, AVG(saldo) AS media_sucursal - Π nombre_sucursal ???

我把???符号,因为这是我不明白的部分:

如果 SELECT 子句是 SQL 查询的最后一部分,我如何将聚合函数的结果重命名为“media_sucursal”并且在 HAVING 子句中可以使用它?

我检查了这个question,但它证实了我上面所说的,但没有回答我的问题。

欢迎任何帮助!

【问题讨论】:

    标签: mysql sql relational-algebra


    【解决方案1】:

    这是MySql扩展GROUP BY的行为

    MySQL Extensions to GROUP BY
    MySQL 扩展了这种行为允许在 聚合列的 HAVING 子句

    您可以使用 sql_mode ONLY_FULL_GROUP_BY 禁用该扩展程序

    SET [SESSION | GLOBAL] sql_mode = ONLY_FULL_GROUP_BY;
    

    如果您尝试在ONLY_FULL_GROUP_BY sql_mode 中执行上述查询,您将收到以下错误消息:

    在 HAVING 子句中使用了非分组字段“media_sucursal”:SELECT nombre_sucursal, AVG(saldo) AS media_sucursal FROM cuenta GROUP BY nombre_sucursal HAVING media_sucursal > 800

    正如预期的那样。

    SQLFiddle 演示说明了这一点。

    【讨论】:

    • 该死!这意味着如果我将来更改 DBMS(例如 SQL Server),我将拥有 SQL 标准之外的其他功能和扩展?
    • 不幸的是,是的。有很多东西是特定于供应商的。但在这种特殊情况下,您可以在 HAVING 子句中使用带有聚合函数的表达式,而不是别名。这在所有主要的 RDBMS 中都是一样的。
    • 是的,mysql 默认开启这个功能来诱使来自其他 DBMS 的用户自满,这有点烦人。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    • 2021-02-06
    • 2020-07-07
    • 2014-07-02
    • 2015-04-16
    相关资源
    最近更新 更多