0

私のSQLクエリは次のとおりです

IF @StatusId = 10
    BEGIN
        SELECT 
            *
        FROM 
        Risk AS R
        INNER JOIN Statuses AS St ON R.Status_Id=St.Status_Id
        WHERE
        R.MitigationOwner = COALESCE(@MitigationOwner,R.MitigationOwner)
        AND R.RiskFactor = COALESCE(@RiskFactor,R.RiskFactor)
        AND R.RiskArea = COALESCE(@RiskArea,R.RiskArea)
        AND R.AddedWhen BETWEEN 
        COALESCE(CONVERT(DATETIME, @StartDate+'00:00:00',120),R.AddedWhen) AND 
        COALESCE(CONVERT(DATETIME,@EndDate+'23:59:59',120),R.AddedWhen)
    END 

ステータスIDのみを渡し、他のすべての変数がnullの場合、NULLのMitigationOwnerまたはModifiedDateのレコードは表示されません。このクエリの何が問題になっていますか?

4

3 に答える 3

4

次のフォームを使用します。

...
(R.MitigationOwner = @MitigationOwner OR  @MitigationOwner IS NULL)
...

これはSQLServerで最適化されています。COALESCEはそうではありません。

編集:これはPaul Williamsの回答と同じですが、彼の回答では明示的な「NULL=NULL」の一致が許可されています。NULLがNULLと等しくなることはないため、mylogicはより単純です。

于 2012-04-05T12:24:17.427 に答える
1

ModifiedDateとは、R.AddedWhenを意味していると思います。

これを試して:

SELECT 
            *
        FROM 
        Risk AS R
        INNER JOIN Statuses AS St ON R.Status_Id=St.Status_Id
        WHERE
        (R.MitigationOwner = COALESCE(@MitigationOwner,R.MitigationOwner) OR R.MitigationOwner IS NULL)
        AND R.RiskFactor = COALESCE(@RiskFactor,R.RiskFactor)
        AND R.RiskArea = COALESCE(@RiskArea,R.RiskArea)
        AND (R.AddedWhen BETWEEN 
        COALESCE(CONVERT(DATETIME, @StartDate+'00:00:00',120),R.AddedWhen) AND 
        COALESCE(CONVERT(DATETIME,@EndDate+'23:59:59',120),R.AddedWhen) OR R.AddedWhen IS NULL)
于 2012-04-05T12:22:53.240 に答える
1

R.MitigationOwnerがnullになる可能性がある場合、比較句は次のようになります。

WHERE
R.MitigationOwner = COALESCE(@MitigationOwner,R.MitigationOwner) 

NULL値を処理するように書き直す必要があります。

WHERE
((R.MitigationOwner IS NULL AND @MitigationOwner IS NULL)
 OR (R.MitigationOwner = @MitigationOwner))

NULLについては、ウィキペディアのこの記事を参照してください。

于 2012-04-05T12:25:48.567 に答える