MySQL 行为不正常

标签 mysql stored-procedures having

我有一个问题:

SELECT I.Id
    , CAST(SUBSTRING_INDEX(GROUP_CONCAT(I.StatusId ORDER BY I.TransactionId DESC), ',', 1) AS UNSIGNED) AS StatusId
    , SUM(I.RefundAmount) AS RefundAmount
    FROM (
        SELECT I.Id
            , IT.Id AS TransactionId
            , IT.StatusId
            , IF(IT.TypeId = 2, IT.RefundAmount, 0) AS RefundAmount
            FROM Items I
            INNER JOIN ItemTransactions IT ON IT.ItemId = I.Id
            WHERE I.Id = someValue
    ) I
    GROUP BY I.Id
    HAVING StatusId = 1 AND RefundAmount = 0

其中 Items 表有交易记录存储在 ItemTransactions 表中。直到这次我一直在使用这种类型的查询并为我工作,having 子句出现了一些问题。

查询在SQL 编辑器 中有效,但在存储过程 中使用时无法正常工作。 (不要误会我的意思,我的大部分存储过程 都使用了这个查询)。逐行调试,发现having子句有问题。

作为临时修复,我将查询更改为:

SELECT I.Id
    , I.StatusId
    , I.RefundAmount
    FROM (
        SELECT I.Id
            , CAST(SUBSTRING_INDEX(GROUP_CONCAT(I.StatusId ORDER BY I.TransactionId DESC), ',', 1) AS UNSIGNED) AS StatusId
            , SUM(I.RefundAmount) AS RefundAmount
            FROM (
                SELECT I.Id
                    , IT.Id AS TransactionId
                    , IT.StatusId
                    , IF(IT.TypeId = 2, IT.RefundAmount, 0) AS RefundAmount
                    FROM Items I
                    INNER JOIN ItemTransactions IT ON IT.ItemId = I.Id
                    WHERE I.Id = someValue
            ) I
            GROUP BY I.Id
            --HAVING StatusId = 1 AND RefundAmount = 0
    ) I
    WHERE I.StatusId = 1 AND I.RefundAmount = 0

查询工作正常。但我想知道是否有人已经遇到过这个问题,并找到了解决办法。我正在使用 MySQL 5.0

谢谢

最佳答案

WHERE 子句用于过滤数据上的通用属性和表达式。 HAVING 子句用于在执行分组后过滤数据,它的参数应该是 GROUP BY 子句的参数,或者包含聚合函数的表达式。 在 WHEREGROUP BYHAVING 子句中使用列的别名也是非法的,但它确实适用于 ORDER BY 子句。

如您所见,一个选项是使用子查询,然后列引用将起作用。 另一种方法是在 HAVING 子句中复制整个表达式:

SELECT I.Id,
    CAST(SUBSTRING_INDEX(GROUP_CONCAT(I.StatusId ORDER BY I.TransactionId DESC),
           ',', 1) AS UNSIGNED) AS StatusId,
    SUM(I.RefundAmount) AS RefundAmount
    FROM (
        SELECT I.Id
            , IT.Id AS TransactionId
            , IT.StatusId
            , IF(IT.TypeId = 2, IT.RefundAmount, 0) AS RefundAmount
            FROM Items I
            INNER JOIN ItemTransactions IT ON IT.ItemId = I.Id
            WHERE I.Id = someValue
    ) I
    GROUP BY I.Id
    HAVING
    CAST(SUBSTRING_INDEX(GROUP_CONCAT(I.StatusId ORDER BY I.TransactionId DESC),
         ',', 1) AS UNSIGNED) = 1
    AND SUM(I.RefundAmount) = 0;

编辑: 仔细观察导致了这个问题 Using column alias in WHERE clause of MySQL query produces an errorMySQL documentation , 这概述了可以在 GROUP BYHAVINGORDER BY 子句中使用列别名,如果这些别名用反引号引起来,例如:

...
HAVING `StatusId` = 1 AND `RefundAmount` = 0

关于MySQL 行为不正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11880884/

相关文章:

ASP.NET配置MySQL数据库?

mysql - 带循环的动态添加列

MYSQL 语句在框架中输入时工作,保存 mysql 时无法让框架使用函数

sql - Mysql:如何选择具有特定值的组?

mysql - mysql 导入时出现错误 #1064,mysql 5.5 到 mariadb 10.0

mysql 无法启动-innoDB : Database was not shut down normally

mysql - SQL - GROUP BY 有计数,连接多个表

mysql - 我可以在不覆盖默认分页的情况下对自定义查询进行分页吗?

mysql - 从类别中选择项目,并且该项目也应该属于另一个类别

sql - SSIS 存储过程调用