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 MitigationOwner 或 ModifiedDate 的记录。这个查询有什么问题?

4

3 回答 3

4

使用表格:

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

这在 SQL Server 中进行了优化。COALESCE 不是。

编辑:这与 Paul Williams 的回答相同,但他的回答允许明确的“NULL = NULL”匹配。我的逻辑更简单,因为 NULL 从不等于 NULL。

于 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 可以为空,那么您的比较子句:

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

必须重写以处理 NULL 值:

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

请参阅Wikipedia 上关于 NULL 的这篇文章

于 2012-04-05T12:25:48.567 回答