Sql 在WHERE子句中应用条件筛选
我在SELECT语句中加入了几个表,如下所示,它有三个参数Sql 在WHERE子句中应用条件筛选,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,我在SELECT语句中加入了几个表,如下所示,它有三个参数 DECLARE @Jobid INT=0, @leadid INT=0, @employeeid INT=0 SELECT e.id, l.id, j.id, e.NAME, l.NAME, j.NAME FROM employee e INNER JOIN leads l
DECLARE @Jobid INT=0,
@leadid INT=0,
@employeeid INT=0
SELECT e.id,
l.id,
j.id,
e.NAME,
l.NAME,
j.NAME
FROM employee e
INNER JOIN leads l
ON e.leadid = l.id
INNER JOIN Jobs j
ON j.id = e.Jobid
无需过滤即可正常工作
在WHERE子句中,我必须添加如下内容。如果三个ID中的任何一个大于0,那么我必须考虑WHERE子句中的筛选器;如果它等于零,我就不考虑那个特殊的条件。< /P>
If @jobid> 0
then introduce this condition in where clause (j.id=@jobid)
If @leadid> 0
then introduce this condition in where clause (l.id=@leadid)
If @employeeid> 0
then introduce this condition in where clause (e.id=@employeeid)
我知道如何通过动态SQL实现这一点,但我需要一个静态SQL语句来实现这一点
我尝试了以下方法:
where
((J.Id = @Jobid and @Jobid>0 )
or @Jobid=0)
and (
(L.Id = @leadid and @leadid>0 )
or @leadid=0
)
and (
(e.Id = @employeeid and @employeeid >0 )
or @employeeid =0
)
但有一个性能的打击
请建议我在静态SQL中执行此操作的其他更好方法,特别是在使用Case时。首先,可以替换此J.Id=@Jobid和@Jobid>0或@Jobid=0
使用@Jobid=0或J.Id=@Jobid。
请注意,由于0显然不是职务id、员工或领导的有效值,因此and部分与此无关,因为任何记录都不会包含id 0
第二,不要使用0作为无效值,而是使用null。这不会影响性能,但这是一个更好的编程习惯,因为0在其他情况下很可能是一个有效值
第三,众所周知,catch-all查询会受到性能影响,特别是在存储过程中,因为缓存的执行计划可能不是当前执行的最佳执行计划。据我所知,处理此问题的最佳方法是向查询中添加重新编译提示,如和中所建议
因此,我建议您的查询如下所示:
CREATE PROCEDURE <procedure name>
(
@Jobid INT=NULL,
@leadid INT=NULL,
@employeeid INT=NULL
)
AS
SELECT e.id,
l.id,
j.id,
e.NAME,
l.NAME,
j.NAME
FROM employee e
INNER JOIN leads l
ON e.leadid = l.id
INNER JOIN Jobs j
ON j.id = e.Jobid
WHERE (@Jobid IS NULL OR J.Id = @Jobid)
AND (@leadid IS NULL OR l.Id = @leadid)
AND (@employeeid IS NULL OR e.Id = @employeeid)
OPTION(RECOMPILE)
GO
通过对表进行正确的索引,通常可以提高select性能。然而,正确地索引需要并非所有开发人员都具备的知识。这是一个很值得一读的主题。我会的。您可以使用这样的CASE表达式:
CREATE PROCEDURE <procedure name>
(
@Jobid INT=NULL,
@leadid INT=NULL,
@employeeid INT=NULL
)
AS
SELECT e.id,
l.id,
j.id,
e.NAME,
l.NAME,
j.NAME
FROM employee e
INNER JOIN leads l
ON e.leadid = l.id
INNER JOIN Jobs j
ON j.id = e.Jobid
WHERE (@Jobid IS NULL OR J.Id = @Jobid)
AND (@leadid IS NULL OR l.Id = @leadid)
AND (@employeeid IS NULL OR e.Id = @employeeid)
OPTION(RECOMPILE)
GO
案例
当@Jiobid超过0时,它将与J.id进行比较。当不是J.id时,将其与自身进行比较,这当然会导致匹配
就我个人而言,我更喜欢@jarlh在上述评论中提出的方法。这种简单性使代码更容易理解
@jarlh示例
如果这些方法不能提高您的性能,请尝试在问题中添加您的模式和一些示例记录。你也可以考虑发布执行计划。检查这个。简单J.ID= @ JOBID或@ JOBID=0等也会这样做。不知道会不会更快…@Mihail:我不是在找动态的SQL@jarlh:谢谢你Jarlh非常感谢你的建议。我已经选择了目标数据应答。无论如何,我会投赞成票。你也应该看看@ZoharPeled的答案。他/她在0的使用上提出了一个很好的观点。关于这个答案,有一点是——在目标列J.Id可为null的情况下,它可能会导致不正确的结果,因为null=null将计算为false。除此之外,在测试用例时,我没有看到性能的变化……当版本更新时,所以在作者看来,这是一个关于什么更具可读性的问题。
WHERE
(J.Id = @Jobid or @Jobid=0)