JOIN ... ON ... JOIN ... ON和JOIN ... JOIN ... ON ... ON之间的区别

时间:2018-08-06 11:28:57

标签: sql database-agnostic

以下内容之间有什么区别?

FROM
table1
    LEFT JOIN table2
    ON table1.key = table2.key
    LEFT JOIN table3
    ON table2.key = table3.key

和:

FROM
table1
    LEFT JOIN table2
        LEFT JOIN table3
        ON table2.key = table3.key
    ON table1.key = table2.key

结果似乎是相同的...

因为有评论和答案说第二种语法无效,所以我将澄清-MSSQL和PostgreSQL都接受两种变体都很好。我还使用一个平台,该平台具有自己的TSQL实现,可以将其自己的实现转换为它实际连接到的提供程序中的一个,而第二个变体是默认情况下如何从可视编辑器中编写代码。

在第一个答案之后,我决定添加一个更复杂的第二种示例:

SELECT
table1.Name AS MainData,
table3ParentParent.Name AS AdditionalData
FROM table1
LEFT JOIN table2
    JOIN table3
        JOIN table3 AS table3Parent
            JOIN table3 AS table3ParentParent
            ON table3Parent.Parent = table3ParentParent.key
        ON table3.Parent = table3Parent.key
    ON table2.table3_id = table3.key
ON table1.table2_id = table2.key

我已经将表的名称更改为无意义的,因为真实的表是俄语的,无论如何也不会告诉您任何信息,但这是我现在正在处理的查询的一部分。另外,我想指出的是,我并不是在寻求优化查询的建议,如果有人发现它不是次优的,我希望了解语法是否有实际的区别,或者仅仅是外观上的区别。 >

2 个答案:

答案 0 :(得分:2)

第一个被评估为:

FROM (table1 LEFT JOIN
      table2
      ON table1.key = table2.key
     ) LEFT JOIN
     table3
     ON table2.key = table3.key

第二个被评估为:

FROM table1 LEFT JOIN
     (table2 LEFT JOIN
      table3
      ON table2.key = table3.key
     )
     ON table1.key = table2.key

因此,首先评估LEFT JOINtable2之间的table3。在第一个查询中,对它进行第二次评估。

这有区别吗?在这种情况下,我认为没有区别。在微妙的边缘条件下,JOIN的其他一些组合可以使顺序有所不同。

答案 1 :(得分:1)

在某些数据库中,联接表达式的“语法”是 递归 定义的。下面是简化的示例:

MySQL

join_table:
    table_reference [INNER|CROSS] JOIN table_factor [join_condition]
  | table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition


table_reference:
    table_factor
  | join_table


table_factor:
    tbl_name

SQL Server

<joined_table> ::=
{
    <table_source> <join_type> <table_source> ON <search_condition>
    | <table_source> CROSS JOIN <table_source>
}


<table_source> ::=
{
    table_or_view_name
    | <joined_table>
}


<join_type> ::=
    [ { INNER | { { LEFT | RIGHT | FULL } [ OUTER ] } } ] JOIN

这意味着以下内容完全正确(如果语法如此):

FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON t2.key = t3.key ON t1.key = t2.key

语法还说明上述查询与以下内容相同:

FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.key = t3.key) ON t1.key = t2.key

您可以根据上述信息将复杂查询转换为简单查询。以下查询:

SELECT *
FROM table1
LEFT JOIN table2
    JOIN table3
        JOIN table3 AS table3Parent
            JOIN table3 AS table3ParentParent
            ON table3Parent.Parent = table3ParentParent.key
        ON table3.Parent = table3Parent.key
    ON table2.table3_id = table3.key
ON table1.table2_id = table2.key

可以写为:

SELECT *
FROM table1
LEFT JOIN (table2
    JOIN (table3
        JOIN (table3 AS table3Parent
            JOIN table3 AS table3ParentParent
            ON table3Parent.Parent = table3ParentParent.key)
        ON table3.Parent = table3Parent.key)
    ON table2.table3_id = table3.key)
ON table1.table2_id = table2.key

展开括号后,从内部开始,您将得到以下信息(注意,LEFT变为RIGHT):

SELECT *
FROM table3 AS table3Parent
JOIN table3 AS table3ParentParent ON table3Parent.Parent = table3ParentParent.key
JOIN table3 ON table3.Parent = table3Parent.key
JOIN table2 ON table2.table3_id = table3.key
RIGHT JOIN table1 ON table1.table2_id = table2.key
相关问题