SQL Server 2005/2008条件连接

4
有没有类似条件连接的东西:
SELECT *
FROM TABLE1 A
    IF (a=='TABLE2') THEN INNER JOIN TABLE2 B ON A.item_id=B.id
    ELSE IF (a=='TABLE3') THEN INNER JOIN TABLE3 C ON A.item_id=C.id

当a是TABLE1中的一个字段时。

我希望在存储过程中使用它,而不使用动态SQL(不将查询写成字符串和EXEC(@query))。

编辑:我不能写:

IF (a=='TABLE2) THEN queryA
ELSE IF (a=='TABLE3') THEN queryB

因为a是TABLE1的一个字段。

2个回答

5

编辑: 根据下面的评论修改了答案:

你可以尝试使用一些左连接来变得聪明。这将返回更多的列,所以你可能想要更加具体地选择而不是只有SELECT *

SELECT *
    FROM TABLE1 A
        LEFT JOIN TABLE2 B
            ON A.item_id = B.id
                AND A.a = 'TABLE2'
        LEFT JOIN TABLE3 C
            ON A.item_id = C.id
                AND A.a = 'TABLE3'
    WHERE (B.id IS NOT NULL AND A.a = 'TABLE2')
       OR (C.id IS NOT NULL AND A.a = 'TABLE3')

@Naor:根据您的评论修改了我的答案。 - Joe Stefanelli
2
我想补充一点,在输出列表中可能需要将B和C中的某些列COALESCE在一起,否则调用者将需要区分1)可能具有相同名称的列和2)重复分支逻辑。 - Cade Roux
@Cade Roux:+1。这正是我所说的,他会比“SELECT *”更加有选择性。谢谢你比我说得更好。 - Joe Stefanelli
@Naor:是的,这就是在连接条件中包含 A.a 检查的目的。 - Joe Stefanelli
@Naor - 这个条件阻止了它在ID匹配的情况下逻辑应用,因为只有一个(或两个都不)分支可以为真。选择实际连接机制来满足查询将在很大程度上取决于索引。 - Cade Roux
显示剩余3条评论

0

根据要求更新了查询:

SELECT * FROM
(
    SELECT * 
        FROM TABLE1 A  INNER JOIN TABLE2 B 
            ON A.a='TABLE2' --This will eleminate the table rows if the value of A.a is not 'TABLE2' 
         AND A.item_id=B.id) A,
             (SELECT * FROM
             INNER JOIN TABLE3 C 
            ON A.a='TABLE3' --This will eleminate the table rows if the value of A.a is not 'TABLE3'
            AND A.item_id=C.id 
                ) B
) a

由于A.a无法同时满足两个条件,因此其中一个INNER JOIN将失败,查询将不返回任何结果。您应该使用LEFT JOIN,就像我的答案中所述一样。 - Joe Stefanelli
在单击“提交”后意识到:)。更改了查询。 - Chandu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接