2014-01-10 18 views
1

我有一个包含一个逗号分隔的是,在我的SELECT语句中的一列整数列表中的VARCHAR输入变量。我知道如何分割的列表,并使用在where子句中,例如:SQL为包括基于列表中输入变量或行中的所有行,如果变量是空

DECLARE @ListOfAges Varchar 
SET @ListOfAges = '15,20,25' 

select p.Name, a.Age 
from People p 
left join Ages a on p.AgeKey = a.AgeKey 
Where a.Age in (dbo.Split(@ListOfAges)) 

我想要做的是,如果@ListOfAges var为空,选择一切,所以是这样的:

select p.Name, a.Age 
from People p 
left join Ages a on p.AgeKey = a.AgeKey 
Where (@ListOfAges = null OR a.Age in (dbo.Split(@ListOfAges))) 

这是有办法做到这一点,执行得更好?可能没有在WHERE子句中使用IN子句?我不确定是否可以在连接中包括这个,或者建议采用完全不同的方法(例如不使用逗号分隔的输入变量)。

谢谢!

+0

当用(in in(15,20,25)''替换in(dbo.Split(@ListOfAges))'时,性能如何?它实质上更好吗?这是您可以通过消除分割而无需其他操作来实现的性能上限。如果这种表现不可接受,那么您可能需要查看是否还有其他需要优化的内容。 – dasblinkenlight

回答

1

函数调用中的WHERE子句放慢你失望。这种做法是不显着提高,但应该有点帮助..

WHERE (@ListOfAges is NULL OR 
     CHARINDEX(','+TRIM(STR(A.AGE))+',',','[email protected]+',')) > 0) 

同样,并不是一个理想的方法,但应该执行比函数调用更好。

我会尝试以下方法来优化性能..

  • 随着年龄的列表中创建一个临时表。
  • LEFT JOIN此表与中世纪的a.Age使用别名TT
  • WHERE子句应

    WHERE @ListOfAges为空或不是ISNULL(TT.Age)

0
select p.Name, a.Age 
from People p 
left join Ages a on p.AgeKey = a.AgeKey 
inner join dbo.Split(@ListOfAges) s on a.Age = s.Age 
UNION ALL 
select p.Name, a.Age 
from People p 
left join Ages a on p.AgeKey = a.AgeKey 
WHERE @ListOfAges IS NULL 
0
DECLARE @ListOfAges Varchar 
SET @ListOfAges = '15,20,25' 


if @ListOfAges in ('15,20,25') 



select p.Name, a.Age 
from People p 
left join Ages a on p.AgeKey = a.AgeKey 
Where a.Age in (dbo.Split(@ListOfAges)) 


else 

select p.Name, a.Age 
from People p 
left join Ages a on p.AgeKey = a.AgeKey