最后收集的SQL语句都加入了ON语句

时间:2017-09-28 16:07:05

标签: sql-server join

有人可以解释一下这种联接的逻辑吗?

SELECT 1
FROM   TABLE1 t1
       RIGHT JOIN TABLE2 t2
               ON t1.ID = t2.ID1
       RIGHT JOIN TABLE3 t3
                  INNER JOIN TABLE4 t4
                          ON t3.ID = t4.ID3
                  INNER JOIN TABLE5 t5
                             INNER JOIN TABLE6 t6
                                     ON t5.ID = t6.ID5
                             INNER JOIN TABLE7 t7
                                        INNER JOIN TABLE8 t8
                                                   INNER JOIN TABLE9 t9
                                                              INNER JOIN TABLE0 t0
                                                                      ON t9.ID0 = t0.ID
                                                           ON t8.ID = t9.ID8
                                                ON t7.ID = t9.ID7
                                     ON t6.ID = t9.ID6
                          ON t4.ID9 = t9.ID
               ON t2.ID6 = t6.ID 

我希望它可以翻译成这样的东西......

select 1
FROM    TABLE1 t1
        RIGHT JOIN TABLE2 t2 ON t1.ID = t2.ID1
        INNER JOIN TABLE6 t6 ON t2.ID6 = t6.ID
        INNER JOIN TABLE9 t9 ON t6.ID = t9.ID6
        INNER JOIN TABLE4 t4 ON t4.ID9 = t9.ID 
        RIGHT JOIN TABLE3 t3 ON t3.ID = t4.ID3
        INNER JOIN TABLE5 t5 ON t5.ID = t6.ID5
        INNER JOIN TABLE7 t7 ON t7.ID = t9.ID7
        INNER JOIN TABLE8 t8 ON t8.ID = t9.ID8
        INNER JOIN TABLE0 t0 ON t9.ID0 = t0.ID 

......但事实并非如此。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

根据SQL-92 standard,第180页,ON子句是合格连接的一部分。 ONJOIN一起使用。

你可以说,

join R on X join S on Y

但不要被愚弄(就像我一样),你不能说

join R join S on X on Y

因为JOIN是递归的,正如What does the position of the ON clause actually mean的已接受答案所解释的那样。

R join S中,S的格式为T join U,所以你得到的是

在X

上加入R(在Y上加入S)

Martin Smith提示,指出正确的答案。

答案 1 :(得分:0)

这是完全有效的标准SQL

FROM   A
       JOIN B
            JOIN C
              ON <<pred1>>
         ON <<pred2>>

相当于

FROM   A
       JOIN (SELECT ...
             FROM   B
                    JOIN C
                      ON <<pred1>>)
         ON <<pred2>>

因此,您的具体案例会转换为

WITH t90
     AS (SELECT t9.ID  AS t9_Id,
                t0.ID  AS t0_Id,
                t9.ID6 AS t9_ID6,
                t9.ID7 AS t9_ID7,
                t9.ID8 AS t9_ID8
         FROM   TABLE9 t9
                INNER JOIN TABLE0 t0
                  ON t9.ID0 = t0.ID),
     T890
     AS (SELECT t8.ID AS t8_Id,
                t90.t9_Id,
                t90.t0_Id,
                t90.t9_ID6,
                t90.t9_ID7
         FROM   TABLE8 t8
                INNER JOIN t90
                  ON t8.ID = t90.t9_ID8),
     T7890
     AS (SELECT t7.ID AS t7_Id,
                T890.t8_Id,
                T890.t9_Id,
                T890.t0_Id,
                T890.t9_ID6
         FROM   TABLE7 t7
                INNER JOIN T890
                  ON t7.ID = t9_ID7),
     T567890
     AS (SELECT T7890.*,
                T6.ID AS T6_Id
         FROM   TABLE5 t5
                INNER JOIN TABLE6 t6
                  ON t5.ID = t6.ID5
                INNER JOIN T7890 T7890
                  ON t6.ID = T7890.t9_ID6),
     T34567890
     AS (SELECT T567890.t6_ID
         FROM   TABLE3 t3
                INNER JOIN TABLE4 t4
                  ON t3.ID = t4.ID3
                INNER JOIN T567890
                  ON t4.ID9 = T567890.t9_Id)
SELECT 1
FROM   TABLE1 t1
       RIGHT JOIN TABLE2 t2
         ON t1.ID = t2.ID1
       RIGHT JOIN T34567890
         ON t2.ID6 = T34567890.t6_ID 

答案 2 :(得分:-1)

它们不一样,因为紧接着之后  RIGHT JOIN,LEFT join或inner join应指定ON。 (没有它将类似于完全不同的交叉连接。)

所以是的,顶级代码与底部代码完全不同。

此外,您不能将多个ON紧接在一起,如果您有多个要加入的列,则应在任何ON子句之前使用INNER JOIN。