SQL连接格式 - 嵌套的内连接

Tim*_*eel 22 sql t-sql sql-server sql-server-2005

我在重构的遗留系统中有以下SQL语句.对于这个问题,这是一个简略的视图,暂时只返回count(*).

SELECT COUNT(*)
FROM Table1 
    INNER JOIN Table2 
        INNER JOIN Table3 ON Table2.Key = Table3.Key AND Table2.Key2 = Table3.Key2 
    ON Table1.DifferentKey = Table3.DifferentKey
Run Code Online (Sandbox Code Playgroud)

它产生了大量的记录并杀死了系统,但有人可以解释一下语法吗?这可以用其他任何方式表达吗?

  • 表1包含419行
  • 表2包含3374行
  • 表3包含28182行

编辑:

建议重新格式化

SELECT COUNT(*)
FROM Table1 
    INNER JOIN Table3
          ON Table1.DifferentKey = Table3.DifferentKey
    INNER JOIN Table2 
          ON Table2.Key = Table3.Key AND Table2.Key2 = Table3.Key2
Run Code Online (Sandbox Code Playgroud)

DRa*_*app 19

为了便于阅读,我重新构建了查询...从表观最高级别为Table1开始,然后与Table3绑定,然后table3与table2绑定.如果你遵循关系链,就会更容易理解.

现在,回答你的问题.作为笛卡尔积的结果,你得到了很大的数量.对于Table1中与Table3匹配的每条记录,您将拥有X*Y.然后,对于table3和Table2之间的每个匹配将产生相同的影响... Y*Z ...因此,您在表1中只有一个可能的ID的结果可以有X*Y*Z记录.

这是基于不知道表格的规范化或内容如何...如果密钥是PRIMARY密钥.

Ex:
Table 1       
DiffKey    Other Val
1          X
1          Y
1          Z

Table 3
DiffKey   Key    Key2  Tbl3 Other
1         2      6     V
1         2      6     X
1         2      6     Y
1         2      6     Z

Table 2
Key    Key2   Other Val
2      6      a
2      6      b
2      6      c
2      6      d
2      6      e
Run Code Online (Sandbox Code Playgroud)

因此,表1加入表3将导致(在这种情况下)有12条记录(每条记录在1中加入,每条记录在3中).然后,再次对表2中的每个匹配记录(5条记录)进行计时...将返回总计60(3 tbl1*4 tbl3*5 tbl2)计数.

所以,现在,根据你的1000条记录进行扩展,你会看到一个混乱的结构如何扼杀一头牛(可以这么说)并杀死性能.

SELECT
      COUNT(*)
   FROM
      Table1 
         INNER JOIN Table3
            ON Table1.DifferentKey = Table3.DifferentKey
            INNER JOIN Table2
               ON Table3.Key =Table2.Key
               AND Table3.Key2 = Table2.Key2 
Run Code Online (Sandbox Code Playgroud)


I a*_*ica 14

既然您已经收到了有关查询的帮助,我会捅你的语法问题:

第一个查询使用一些鲜为人知的ANSI SQL语法,允许您在joinon子句之间嵌套连接.这允许您对连接进行范围/分层,并可能打开许多其他邪恶,神秘的东西.

现在,当一个嵌套连接不能引用比它的直接父在加入任何层次更高,连接在它上面或其分支之外的可以参考一下吧......这恰恰是这个丑陋的小家伙正在做:

select
 count(*)
from Table1 as t1
join Table2 as t2
    join Table3 as t3
    on t2.Key = t3.Key                   -- join #1
    and t2.Key2 = t3.Key2 
on t1.DifferentKey = t3.DifferentKey     -- join #2  
Run Code Online (Sandbox Code Playgroud)

这看起来有点令人困惑,因为连接#2将t1连接到t2而没有特别引用t2 ...但是,它通过t3间接引用t2,而t3连接到连接#1中的t2.虽然这可能有效,但您可能会发现以下内容更多(视觉上)线性且吸引人:

select
 count(*)
from Table1 as t1
    join Table3 as t3
        join Table2 as t2
        on t2.Key = t3.Key                   -- join #1
        and t2.Key2 = t3.Key2   
    on t1.DifferentKey = t3.DifferentKey     -- join #2
Run Code Online (Sandbox Code Playgroud)

就我个人而言,我发现以这种方式嵌套可以通过概述关系层次结构的每一层来保持我的陈述整洁.作为旁注,您不需要指定内部.除非另有明确标记,否则join是隐式内部的.