如果已找到结果集,则忽略其他结果
Ignore other results if a resultset has been found
首先,以这个片段为例:
SELECT *
FROM StatsVehicle
WHERE ((ReferenceMakeId = @referenceMakeId)
OR @referenceMakeId IS NULL)
如果变量@referenceMakeId 不为空,这将获取并过滤记录,如果为空,将获取所有记录。换句话说,如果@referenceMakeId 不为空,它会考虑第一个。
我想对此添加进一步的限制,我该如何实现?
例如
(ReferenceModelId = @referenceModeleId) OR
(
(ReferenceMakeId = @referenceMakeId) OR
(@referenceMakeId IS NULL)
)
如果@referenceModelId不为null,则只需要通过ReferenceModelId进行过滤,忽略其中的其他语句。如果我真的这样做,它 returns 所有记录。有什么办法可以实现这样的事情吗?
也许是这样的?
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)
)
)
这应该可以解决问题。
SELECT * FROM StatsVehicle
WHERE ReferenceModelId = @referenceModeleId OR
(
@referenceModeleId IS NULL AND
(
@referenceMakeId IS NULL OR
ReferenceMakeId = @referenceMakeId
)
)
但是,您应该注意,这种类型的查询(称为包罗万象的查询)的效率往往低于为每个案例编写一个查询。
这是因为 SQL 服务器将缓存第一个查询计划,该计划对于其他参数可能不是最优的。
您可能需要考虑使用 OPTION (RECOMPILE)
query hint,或将存储过程分解为多个部分,每个部分将处理特定条件(即一个 select 用于空变量,一个 select 表示非空)。
有关详细信息,请阅读 this article。
If @referenceModelId is not null, it will only need to filter by
ReferenceModelId, and ignore the other statements inside it. If I
actually do this as such, it returns all the records. Is there
anything that can be done to achieve such a thing?
你可以考虑使用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
首先,以这个片段为例:
SELECT *
FROM StatsVehicle
WHERE ((ReferenceMakeId = @referenceMakeId)
OR @referenceMakeId IS NULL)
如果变量@referenceMakeId 不为空,这将获取并过滤记录,如果为空,将获取所有记录。换句话说,如果@referenceMakeId 不为空,它会考虑第一个。
我想对此添加进一步的限制,我该如何实现?
例如
(ReferenceModelId = @referenceModeleId) OR
(
(ReferenceMakeId = @referenceMakeId) OR
(@referenceMakeId IS NULL)
)
如果@referenceModelId不为null,则只需要通过ReferenceModelId进行过滤,忽略其中的其他语句。如果我真的这样做,它 returns 所有记录。有什么办法可以实现这样的事情吗?
也许是这样的?
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)
)
)
这应该可以解决问题。
SELECT * FROM StatsVehicle
WHERE ReferenceModelId = @referenceModeleId OR
(
@referenceModeleId IS NULL AND
(
@referenceMakeId IS NULL OR
ReferenceMakeId = @referenceMakeId
)
)
但是,您应该注意,这种类型的查询(称为包罗万象的查询)的效率往往低于为每个案例编写一个查询。
这是因为 SQL 服务器将缓存第一个查询计划,该计划对于其他参数可能不是最优的。
您可能需要考虑使用 OPTION (RECOMPILE)
query hint,或将存储过程分解为多个部分,每个部分将处理特定条件(即一个 select 用于空变量,一个 select 表示非空)。
有关详细信息,请阅读 this article。
If @referenceModelId is not null, it will only need to filter by ReferenceModelId, and ignore the other statements inside it. If I actually do this as such, it returns all the records. Is there anything that can be done to achieve such a thing?
你可以考虑使用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