如果找到结果集,请忽略其他结果

时间:2015-06-01 09:50:03

标签: sql sql-server tsql stored-procedures

首先,请将此代码段作为示例:

SELECT * 
FROM StatsVehicle 
WHERE ((ReferenceMakeId = @referenceMakeId)
 OR @referenceMakeId IS NULL)

如果变量@referenceMakeId不为null,则将获取并过滤记录;如果变量为null,则将获取所有记录。换句话说,如果@referenceMakeId不为空,则考虑第一个。

我想对此添加进一步的限制,我该如何实现?

例如

(ReferenceModelId = @referenceModeleId) OR
(
    (ReferenceMakeId = @referenceMakeId) OR
    (@referenceMakeId IS NULL)
)

如果@referenceModelId不为null,则只需要按ReferenceModelId进行过滤,并忽略其中的其他语句。如果我实际上这样做,它将返回所有记录。有什么办法可以做到这一点吗?

3 个答案:

答案 0 :(得分:1)

也许是这样的?

SELECT * FROM StatsVehicle WHERE 
( 
    -- Removed the following, as it's not clear if this is beneficial
    -- (@referenceModeleId IS NOT NULL) AND 
    (ReferenceModelId = @referenceModeleId)
) OR
(@referenceModeleId IS NULL AND 
 (
    (ReferenceMakeId = @referenceMakeId) OR
    (@referenceMakeId IS NULL)
 )
)

答案 1 :(得分:0)

这应该可以解决问题。

SELECT * FROM StatsVehicle 
WHERE ReferenceModelId = @referenceModeleId OR
(
@referenceModeleId IS NULL AND 
    (
    @referenceMakeId IS NULL OR
    ReferenceMakeId = @referenceMakeId
    )
)

但是,您应该注意,这种类型的查询(称为catch-all查询)往往效率低于为每个案例编写单个查询。

这是因为SQL Server将缓存可能不是其他参数最佳的第一个查询计划。

您可能需要考虑使用OPTION (RECOMPILE) query hint,或者将存储过程制动为每个处理特定条件的片段(即一个选择空值变量,一个选择非空值)。

有关详情,请参阅this article

答案 2 :(得分:0)

  

如果@referenceModelId不为null,则只需要过滤   ReferenceModelId,并忽略其中的其他语句。如果我   实际上这样做,它返回所有记录。在那儿   什么都可以做到这一点?

您可以考虑使用CASE来获得良好的短路机制

WHERE
    CASE 
        WHEN @referenceModelId is not null AND ReferenceModelId = @referenceModeleId THEN 1
        WHEN @referenceMakeId is not null AND ReferenceMakeId = @referenceMakeId  THEN 1
        WHEN @referenceModelId is null AND @referenceMakeId is null THEN 1
        ELSE 0
    END = 1