2

以下は問題ありませんか?

DELETE a
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData a
WHERE EXISTS
        (
        SELECT * 
        FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData b
        WHERE 
            b.[Past28Days] = 1 AND
            a.[Index] = b.[Index]
        HAVING SUM(b.Amount) = 0
        )

上記のスクリプトの使用に少し不安がある理由は、次のスクリプトを実行するとエラーになるためです。

SELECT * 
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData b
WHERE 
    b.[Past28Days] = 1
HAVING SUM(b.Amount) = 0

このスクリプトがエラーになる理由を理解しています => 選択が何にもグループ化されていないため、プロセッサは HAVING 句の集計を好みません。

しかし、サブクエリとしてこのエラーは発生しません - なぜですか? これは問題のあるアプローチですか?

編集

以下を使用して終了しました:

DELETE a
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData a
WHERE a.[Index] IN
    (
    SELECT [Index] 
    FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData
    WHERE [Past28Days] = 1
    GROUP BY [Index] 
    HAVING SUM(Amount) = 0
    )

しかし、回答で示唆されているように、サブクエリに GROUP BY を追加するだけで、以下が読みやすくなります。

DELETE a
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData a
WHERE EXISTS
    (
    SELECT * 
    FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData b
    WHERE 
            b.[Past28Days] = 1 AND
            a.[Index] = b.[Index]
    GROUP BY b.[Index]
    HAVING SUM(b.Amount) = 0
    )
4

1 に答える 1

2

group by を省略しても集計を実行することは合法であるため、having結果を制限する方法としては依然として有効です。

select sum(x)
from
(
  select 1 x union all select 2
) a
having sum(x) = 3

Exists()選択リスト内のすべてが無視されるため、機能します。Exists()行のみを検索し、見つかるとすぐに終了します。group by b.Index後でコードを確認する人に意図を明確にするために追加するか、内部結合と派生テーブルを使用して書き直すことができます。

DELETE a
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData a
INNER JOIN
        (
        SELECT b.[Index]
        FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData b
        WHERE 
            b.[Past28Days] = 1
        GROUP BY b.[Index]
        HAVING SUM(b.Amount) = 0
        ) b1
   ON a.[Index] = b1.[Index]
于 2012-08-20T10:52:50.497 に答える