LEFT JOIN子句中的INNER JOIN

时间:2014-08-05 16:34:57

标签: sql tsql

我收到一个查询,它使用一些非常奇怪的语法进行连接,我需要了解如何使用这个连接:

SELECT
  T1.Acct#
, T2.New_Acct#
, T3.Pool#
FROM        DB.dbo.ACCT_TABLE       T1
LEFT JOIN   DB.dbo.CROSSREF_TABLE   T2
INNER JOIN  DB.dbo.POOL_TABLE       T3
        ON  T2.Pool# = T3.Pool#
        ON  T1.Acct# = T2.Prev_Acct#
  • T1是一个独特的帐户列表
  • T2是每个Pool#
  • 的不同帐户列表
  • T3是一个独特的列表(帐户组)

我需要为T1中的每条记录返回T2中保存的先前帐号。我还需要为每个池返回T3 Pool#。

我试图理解的是为什么有人会以这种方式编写代码。这对我没有意义。

2 个答案:

答案 0 :(得分:8)

稍微缩进会更好地显示出预期的内容

SELECT
  T1.Acct#
, T2.New_Acct#
, T3.Pool#
FROM        DB.dbo.ACCT_TABLE       T1
LEFT JOIN   DB.dbo.CROSSREF_TABLE   T2
     INNER JOIN  DB.dbo.POOL_TABLE  T3
     ON  T2.Pool# = T3.Pool#
ON  T1.Acct# = T2.Prev_Acct#

这是强制连接顺序的有效语法。基本上它仅询问表T2中也在表T3中的记录,然后将它们连接到T1。我不喜欢它,因为它很难维护。我更喜欢派生表,因为当我需要在六个月后进行维护时,我会发现更清晰,更容易更改:

SELECT
  T1.Acct#
, T2.New_Acct#
, T3.Pool#
FROM        DB.dbo.ACCT_TABLE       T1
LEFT JOIN   (select T2.New_Acct#, T3.Pool#
             FROM DB.dbo.CROSSREF_TABLE   T2
             INNER JOIN  DB.dbo.POOL_TABLE       T3
                ON  T2.Pool# = T3.Pool#) T4
   ON  T1.Acct# = T4.Prev_Acct#

答案 1 :(得分:1)

这里的外部申请会更清楚:

SELECT
    T1.Acct#, 
    T4.New_Acct#, 
    T4.Pool#
FROM DB.dbo.ACCT_TABLE T1
OUTER APPLY  
(
    SELECT 
        T2.New_Acct#, 
        T3.Pool#
    FROM DB.dbo.CROSSREF_TABLE T2
    INNER JOIN DB.dbo.POOL_TABLE T3 ON T2.Pool# = T3.Pool#
    WHERE T1.Acct# = T4.Prev_Acct#
) T4