1

我有一个查询:

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

where Itemstable 有存储在表中的事务记录ItemTransactions。我一直在使用这种类型的查询并为我工作,直到此时,该having子句出现了一些问题。

查询在SQL Editors使用时有效,但在stored procedures. (不要误会我的意思,我的大部分时间都在使用这个查询stored procedures)。逐行调试,发现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.

谢谢

4

1 回答 1

3

WHERE子句用于过滤数据的常用属性和表达式。HAVING子句用于在执行分组后过滤数据,它的参数应该是GROUP BY子句的参数,或者包含聚合函数的表达式。WHERE在, GROUP BYor子句中使用列的别名也是非法的HAVING,但它确实适用于该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 会产生一个错误MySQL 文档,它概述了可以在GROUP BY,HAVINGORDER BY子句中使用列别名,如果这样的别名用反引号引用,比如:

...
HAVING `StatusId` = 1 AND `RefundAmount` = 0
于 2012-08-09T10:50:09.593 回答