您可以以不同的方式构建源表,因此,您可以在合并条件之前构建组合,而不是使用OR
。例如
DECLARE @param1 INT = 1,
@param2 INT = 2,
@param3 INT = 3;
WITH Params AS
( SELECT pValue, pNumber
FROM (VALUES (@param1, 1), (@param2, 2), (@param3, 3)) p (pValue, pNumber)
)
SELECT Col1 = p1.Pvalue, Col2 = p2.Pvalue, Col3 = p3.Pvalue
FROM Params AS P1
INNER JOIN Params AS p2
ON p2.pNumber NOT IN (p1.pNumber)
INNER JOIN Params AS p3
ON p3.pNumber NOT IN (p1.pNumber, p2.pNumber);
这给你的6个组合(每个加盟确保您不会重复使用相同的参数):
Col1 Col2 Col3
------------------
2 3 1
3 2 1
1 3 2
3 1 2
1 2 3
2 1 3
所以你MERGE
条件变得更简单:
WITH Params AS
( SELECT pValue, pNumber
FROM (VALUES (@param1, 1), (@param2, 2), (@param3, 3)) p (pValue, pNumber)
), SourceTable AS
( SELECT Col1 = p1.Pvalue, Col2 = p2.Pvalue, Col3 = p3.Pvalue
FROM Params AS P1
INNER JOIN Params AS p2
ON p2.pNumber NOT IN (p1.pNumber)
INNER JOIN Params AS p3
ON p3.pNumber NOT IN (p1.pNumber, p2.pNumber)
)
MERGE Target_Table AS t
USING SourceTable AS s
ON t.col1 = s.col1
AND t.col2 = s.col2
AND t.col3 = s.col3
WHEN MATCHED THEN […update…]
WHEN NOT MATCHED THEN […insert…];
这也使得更容易添加更多参数,所以第四个参数只需要CTE params
中的额外一行,而不是全新的OR
条件
DECLARE @param1 INT = 1,
@param2 INT = 2,
@param3 INT = 3,
@param4 INT = 4;
WITH Params AS
( SELECT pValue, pNumber
FROM (VALUES (@param1, 1), (@param2, 2), (@param3, 3), (@Param4, 4)) p (pValue, pNumber)
)
SELECT Col1 = p1.Pvalue, Col2 = p2.Pvalue, Col3 = p3.Pvalue
FROM Params AS P1
INNER JOIN Params AS p2
ON p2.pNumber NOT IN (p1.pNumber)
INNER JOIN Params AS p3
ON p3.pNumber NOT IN (p1.pNumber, p2.pNumber);
然后给出所有24个组合,没有太多额外的代码。
根据您列出的内容很难说清楚。任何列可以与其他表中的其他列匹配吗?可读性与性能恕我直言一样重要。虽然我确定你知道,因为你正在使用多个AND/OR操作符,所以要小心记住SQL Server在评估这些操作时的优先级。 https://msdn.microsoft.com/en-us/library/ms190276.aspx – scsimon
嗨,谢谢你的回复。是的,我在源表中使用的三个变量可以以任意顺序匹配目标表中的三列中的任何一列。此外,我已将该示例限制为三个变量,但最多可以有六个。我想看看是否有更好的方法来评估数据并查看是否在任何列中找到变量 – ccalgie
所有参数都是唯一的还是可以使这些值相等?例如,param1和param2都可以是“1”吗? –