条件连接语句

有没有可能做到以下几点:

IF [a] = 1234 THEN JOIN ON TableA
ELSE JOIN ON TableB

如果是,正确的语法是什么?

131615 次浏览

我认为您所要求的将通过使用 LEFT JOIN首字母缩写表连接到 选项 _ A选项 _ B来实现,这将产生类似下面这样的结果:

Initial LEFT JOIN Option_A LEFT JOIN NULL
OR
Initial LEFT JOIN NULL LEFT JOIN Option_B

示例代码:

SELECT i.*, COALESCE(a.id, b.id) as Option_Id, COALESCE(a.name, b.name) as Option_Name
FROM Initial_Table i
LEFT JOIN Option_A_Table a ON a.initial_id = i.id AND i.special_value = 1234
LEFT JOIN Option_B_Table b ON b.initial_id = i.id AND i.special_value <> 1234

一旦你这样做了,你“忽略”的 NULLS 集。这里的附加技巧在 SELECT 行中,您需要决定如何处理 NULL 字段。如果 Option _ A 和 Option _ B 表相似,那么可以使用 COALESCE函数返回第一个 NON NULL 值(如示例所示)。

另一种选择是,您只需列出 Option _ A 字段和 Option _ B 字段,并让使用 ResultSet的任何东西来处理决定使用哪些字段。

我不同意建议两个左连接的解决方案。我认为使用表值函数更合适,这样就不必为每个条件提供所有的合并和附加连接。

CREATE FUNCTION f_GetData (
@Logic VARCHAR(50)
) RETURNS @Results TABLE (
Content VARCHAR(100)
) AS
BEGIN
IF @Logic = '1234'
INSERT @Results
SELECT Content
FROM Table_1
ELSE
INSERT @Results
SELECT Content
FROM Table_2
RETURN
END
GO


SELECT *
FROM InputTable
CROSS APPLY f_GetData(InputTable.Logic) T

这只是添加了一点,即可以根据条件动态构造查询。 下面给出一个例子。

DECLARE @a INT = 1235
DECLARE @sql VARCHAR(MAX) = 'SELECT * FROM [sourceTable] S JOIN ' + IIF(@a = 1234,'[TableA] A ON A.col = S.col','[TableB] B ON B.col = S.col')


EXEC(@sql)
--Query will be
/*
SELECT * FROM [sourceTable] S JOIN [TableB] B ON B.col = S.col
*/

你可以和工会一起解决这个问题

select a, b
from tablea
join tableb on tablea.a = tableb.a
where b = 1234
union
select a, b
from tablea
join tablec on tablec.a = tableb.a
where b <> 1234

我认为以不同的方式思考您的查询会更好,并且更像 设置一样对待它们。

我确实相信如果你做两个单独的查询,然后使用 工会连接它们,它将在性能和可读性方面更好。