2

考虑一个简单的连接:

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

4 回答 4

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 */)
于 2012-04-30T15:20:09.680 回答
1

不幸的是,T-SQL 没有语法来支持这一点。我前段时间对此进行了修补,但无法提出解决方案,直到我发现这篇文章对我有帮助(通过使用左外连接)并且它可能对你有所帮助。它位于这里

于 2012-04-30T15:22:41.880 回答
0

@Gerardo Lima 的回答非常好,但作为替代方案,您可以使用动态 SQL 构建查询。这将允许您使用一系列 if 语句来添加或不添加任意数量的连接,根据需要使用尽可能多的 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

在“动态sql的祸与福”中有对动态sql的很好的讨论

于 2012-04-30T16:05:47.887 回答
0

很好的解决方案,杰拉尔多!使用工会不会对性能造成影响。我不能告诉你为什么(也许有人可以在这里填补空白),但执行计划显示持续扫描的 I/O 成本为 0。

但是,这确实取决于 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

请注意,然后由您的应用程序代码来确定相应的模式并相应地读取数据。

于 2012-04-30T16:23:12.100 回答