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

テーブルItemsには、テーブルに格納されたトランザクション レコードがありItemTransactionsます。私はこのタイプのクエリを使用してきましたが、今回までうまくいきましたが、having句に問題がありました。

クエリは で機能しSQL Editorsますが、 で使用すると正しく機能しませんstored procedures。(誤解しないでください。私はほとんどの .NET でこのクエリを使用しています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句のもの、または集約関数を含む式のいずれかである必要があります。WHEREGROUP BYまたはHAVING句で列のエイリアスを使用することも違法ですが、ORDER BY句では機能します。

あなたが見つけたように、1つのオプションはサブクエリを使用することであり、その後列参照が機能します。HAVINGもう 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
    CAST(SUBSTRING_INDEX(GROUP_CONCAT(I.StatusId ORDER BY I.TransactionId DESC),
         ',', 1) AS UNSIGNED) = 1
    AND SUM(I.RefundAmount) = 0;

編集:よく見てみると、MySQL クエリの WHERE 句で列エイリアスを使用するとエラーが発生し、MySQL のドキュメントGROUP BYに、列エイリアスを使用できることが概説されています。 :HAVINGORDER BY

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