在SQL语句中有条件地添加/删除联接

时间:2014-10-01 03:36:22

标签: sql sql-server tsql

我有一个存储过程,它接受输入两个表类型(每个表类型只包含一个ID列)。这些是需要应用于存储过程内的主查询的过滤器。我是通过使用这两个表类型参数加入主查询来实现的。如下所示:

SELECT 
  <cols> 
FROM 
  <table> t join @tableVar1 v1 on t.c1 = v1.c1 
            join @tableVar2 v2 on t.c2 = v2.c2

现在我需要更改过程,如果表变量不包含任何行,则应返回整个集合。因此,如果@ tableVar1有0行,我不会加入主查询。

我想做的事情和我正在努力的是,如果变量有0行,则有条件地不进行连接。我可以为每个组合添加if语句,但这意味着我必须编写4个查询。查询很复杂我担心之后的更改可能会不同步。

那么可以在同一查询中执行此操作,而对性能影响最小吗?感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

这样的事可能 -

而不是内连接,我使用了左连接,然后所有4个条件都进入了where子句。

declare @countv1 int, @countv2 int
select @countv1 = COUNT(1) from @tableVar1
select @countv2 = COUNT(1) from @tableVar2

SELECT 
  <cols> 
FROM 
  <table> t 
    left join @tableVar1 v1 on t.c1 = v1.c1 
    left join @tableVar2 v2 on t.c2 = v2.c2
where 
    (@countv1=0 or v1.c1 is not null)
    and 
    (@countv2=0 or v2.c1 is not null)

答案 1 :(得分:0)

您可以使用Dynamic SQL Query

来实现条件加入
Declare @CntVar1 int
Declare @CntVar2 int
Declare @ExSQL nvarchar(max)

select @CntVar1 = COUNT(1) from @tableVar1
select @CntVar2 = COUNT(1) from @tableVar2

Set @ExSQL= 'Select <cols> FROM <table> t' 
 IF @CntVar1>=1
 Begin
    Set @ExSQL = @ExSQL + 'join @tableVar1 v1 on t.c1 = v1.c1'
 End 
  IF @CntVar2>=1
 Begin
    Set @ExSQL = @ExSQL +'join @tableVar2 v2 on t.c2 = v2.c2'
 End

Exec Sp_executeSQL @ExSQL  

答案 2 :(得分:0)

另一种可能性可能是:

declare @t1 TABLE (id int)
declare @t2 TABLE (id int)

...

select * from dbtest1 d where 1 =
   (case when not exists(select * from @t1) then 1 
         when exists(select * from @t1 t1 where t1.id = d.id) then 1 end)
 AND 1 = 
    (case when not exists(select * from @t2) then 1 
         when exists(select * from @t2 t2 where t2.id = d.id) then 1 end)

您希望检查查询计划并在特定情况下执行某些计时,以检查效果是否令人满意。