仅当第一个包含某些值时才加入两个表,如果不加入另一个

时间:2013-06-27 17:02:41

标签: sql-server tsql

如果TableA包含TableB值且TableA.Column1numeric,我正在尝试编写一个加入Join另一个TableA的查询如果TableC包含TableA.Column1值,则另一个varchar

有没有办法写这样的查询?

3 个答案:

答案 0 :(得分:2)

这样的事情怎么样?您需要将适当的列投射到某些中间地带。

SELECT * 
FROM TableA a 
INNER JOIN TableB b ON b.Columns1 = a.Column1
    AND ISNUMERIC(a.Column1) = 1
WHERE 1=1
UNION
SELECT * 
FROM TableA a 
INNER JOIN TableC c ON c.Columns1 = a.Column1
    AND ISNUMERIC(a.Column1) = 0

答案 1 :(得分:1)

表设计听起来有问题,但我认为这个查询是实现您所要求的简单方法。

SELECT
    TableA.Column1,
    TableB.Column2,
    TableC.Column2,
    ISNULL(TableB.Column2, TableC.Column2)
FROM TableA
LEFT OUTER JOIN TableB ON
    ISNUMERIC(TableA.Column1) = 1
    AND TableA.Column1 = TableB.Column1
LEFT OUTER JOIN TableC ON
    ISNUMERIC(TableA.Column1) = 0
    AND TableA.Column1 = TableC.column1

正如Mike Cheel指出的那样,你可能需要做一些演员。

此外,使用此方法,您需要考虑TableA中存在与TableB或TableC中的任何内容不匹配的记录的可能性,因为这是使用外部联接。如果您不希望在结果中使用这些记录,则可以使用WHERE子句中的条件排除它们。

答案 2 :(得分:1)

按照JNK的评论,这里有一种方法,您可以通过向表中添加2个Computed列来表示设计问题,至少会尝试将设计问题封装一下,这些列代表INT的占位符和VARCHAR外键。

ALTER TABLE MyTable ADD IntJoinColumn AS 
CASE WHEN ISNUMERIC(BadJoinColumn) = 1 
     THEN CAST(BadJoinColumn AS INT) 
     ELSE NULL 
END;
ALTER TABLE MyTable ADD VarCharJoinColumn AS 
     CASE WHEN ISNUMERIC(BadJoinColumn) = 1 
          THEN NULL 
          ELSE BadJoinColumn 
     END;

然后您可以以更“可读”的方式加入,如下所示:

SELECT mt.* 
    FROM MyTable mt
    INNER JOIN MyIntJoinTable ON IntJoinColumn = MyIntJoinTable.Id 
UNION ALL
SELECT mt.* 
    FROM MyTable mt
INNER JOIN MyVarCharJoinTable ON VarCharJoinColumn = MyVarCharJoinTable.VarCharId;

SQLFiddle Here

NULL映射可以通过在INNER JOIN期间消除它们来过滤掉'不正确'的数据类型。)