2

我正在尝试编写一个查询,该查询连接到另一个TableAifTableB包含TableA.Column1numeric和另一个if包含值。JoinTableATableCTableA.Column1varchar

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

4

3 回答 3

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
于 2013-06-27T17:14:50.423 回答
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 子句中使用条件排除它们。

于 2013-06-27T17:22:54.303 回答
1

按照 JNK 的评论,这是一种可以解决的方法,它至少尝试通过在表中添加 2 个 Computed 列来稍微封装设计问题,这些列代表 theINTVARCHAR外键的占位符。

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 这里

NULL映射具有过滤掉“不正确”数据类型的效果,方法是在INNER JOIN.

于 2013-06-27T17:23:12.200 回答