级联外部联接

时间:2011-02-21 10:57:22

标签: sql-server tsql

作为示意图,我有3个我希望加入的表,A,B,C,其中A到B通过外连接连接,B到C可能通过内连接连接。在这个星座中,如果第一个连接在一行中没有匹配的A-B,我必须编写两个外连接来获取数据:

SELECT [fields] FROM
       A
       LEFT OUTER JOIN
       B ON [a.field]=[b.field] 
       LEFT OUTER JOIN
       C ON [b.field]=[c.field]

在我看来逻辑上我必须将第二个语句写为外连接。但是我很好奇是否有可能为连接范围设置括号,以表示只有在第一个内部连接找到A-B的匹配数据时才应使用第二个连接。类似的东西:

SELECT [fields] FROM
       A
      (LEFT OUTER JOIN
       B ON [a.field]=[b.field] 
       INNER JOIN
       C ON [b.field]=[c.field]
       )

我玩过一点但没有找到设置括号的可能性。我发现使这个工作的唯一方法是使用子查询。这是唯一的出路吗?

4 个答案:

答案 0 :(得分:4)

实际上这种情况有一种语法。

SELECT fields
FROM A
  LEFT OUTER JOIN (
    B INNER JOIN C ON b.field = c.field
  ) ON a.field = b.field

括号是可选的,没有它们的结果是相同的,等同于

的结果
SELECT fields
FROM A
  LEFT OUTER JOIN B ON a.field = b.field
  LEFT OUTER JOIN C ON b.field = c.field

答案 1 :(得分:2)

您可以按照以下方式执行

SELECT Fields 
FROM TableA a
LEFT OUTER JOIN (SELECT Fields
                 FROM TableB b
                 INNER JOIN TableC c ON b.Field = c.Field) x on a.Field = x.Fi

视场

不确定是否会在没有测试的情况下获得任何性能优势。

答案 2 :(得分:1)

根据Jon Bridges的回答,第二种方式是使用子查询

但是,它们在语义上是相同的。

如果您有复杂的子查询

,则可以使用CTE
;WITH BjoinC AS
(
    SELECT Fields
    FROM TableB b
    INNER JOIN
    TableC c ON b.Field = c.Field
)
SELECT [fields] FROM
       A
       LEFT OUTER JOIN
       BjoinC ON ...

答案 3 :(得分:0)

如下所示:

SELECT [fields] 
FROM A 
LEFT JOIN ( SELECT DISTINCT [fields]
            FROM B
            LEFT JOIN C ON b.field = c.field
          ) on a.field = b.field