T-SQL:使用参数有条件地加入

时间:2012-04-30 15:13:40

标签: sql-server tsql join conditional

考虑一个简单的连接:

Select TableB.* 
From TableA 
Inner Join TableB 
    On TableB.ID = TableA.ID

我想要做的是根据参数决定要加入哪个表。虽然以下语法无效,但我写的只是为了说明我的目的:

Select TableD.* 
From TableA 
Inner Join 
    [If @useTableC = 1 Then Join to TableC Else Join to TableB] As TableD

TableB和TableC都有相同的列。

如何创建此类联接。请注意,此示例实际上是更大查询的一小部分,因此您不能只使用If ... Else语句。

非常感谢!

4 个答案:

答案 0 :(得分:6)

通常我更喜欢在多个语句中重写,但如果你真的需要它:

SELECT td.*
FROM TableA ta
JOIN (
    SELECT tc.* FROM TableC Where @useTableC = 1
    UNION ALL
    SELECT tb.* FROM TableB Where @useTableC = 0
) td ON ( /* JOIN CONDITION MISSING */)

答案 1 :(得分:1)

不幸的是,T-SQL没有语法支持这一点。我前段时间修改了这个并且无法提出解决方案,直到我发现这篇文章帮助了我(通过使用Left Outer连接)并且它可能对你有帮助。它位于here

答案 2 :(得分:0)

@Gerardo Lima的答案非常好,但作为替代方案,您可以使用动态SQL构建查询。这将允许您根据需要使用一系列if语句添加或不添加任意数量的连接。粗略粗略的例子:

declare @sql varchar(8000)

set @sql = 'Select TableD.*  From TableA '

if @usertableC = 1 
then select @sql = @sql + ' innner join tableC'

if @usertableC != 1
then select @sql = @sql + ' innner join tableB

exec @sql

"the curse and blessing of dynamic sql"

对动态sql进行了很好的讨论

答案 3 :(得分:0)

很好的解决方案,杰拉尔多!使用联合没有性能损失。我不能告诉你为什么(也许有人可以填补这里的空白),但是执行计划显示了恒定扫描的0 I / O成本。

但是,这确实取决于TableB和TableC的模式是否相同。要使用多个语句,支持TableB和TableC中的不同模式,我会考虑以下方法:

DECLARE @sql NVARCHAR(MAX)
SET @sql = 'SELECT td.* FROM TableA ta INNER JOIN Table' + 
    CASE WHEN @useTableC = 1 THEN 'C' ELSE 'B' END + ' td ON ta.ID = td.ID'
EXEC sp_executesql @sql

请注意,由应用程序代码决定相应的架构并相应地读取数据。