在LEFT JOIN子句中使用INNER JOIN

11

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

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是每个池的独特账户列表#
  • T3是一个独特的列表(一组账户)

我需要为T1中的每个记录返回先前在T2中持有的账户号码。 我还需要为每个池返回T3池#。

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


这让我觉得这是一次编辑...某个原始查询已更新,他们只是在末尾添加了一个INNER JOIN。从功能上讲,在这种情况下,LEFT OUTER JOIN将被强制视为INNER JOIN处理。 - Jeremy Holovacs
只返回在两个中都有匹配的记录,这差不多是我想到的。难道只有我觉得这种写法很懒吗? - iddqd
CROSSREF_TABLE 是另外两个表之间的连接表吗?相关列上是否有外键约束? - ypercubeᵀᴹ
没有外键约束。如果我理解你所说的连接表是什么意思,我认为它是(你需要T2才能从T1到达T3)。 - iddqd
2个回答

15

稍微缩进一下,就能更好地展现原意。

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#

同意。那个用法对我来说也很困惑。 - UnhandledExcepSean
谢谢HLGEM - 这就是我想要的解释。 - iddqd
1
你确定左边在第一个上没有被否定吗? - paparazzo
2
是的,我确定左边没有被否定,不幸的是我们有一个喜欢这种愚蠢写法的开发人员,我每天都看到它。 - HLGEM
不确定你在问什么,@Matthew。 - HLGEM
显示剩余4条评论

1
这里使用 OUTER APPLY 会更清晰:
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

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