我正在阅读一个查询,在连接表时我通常不会在其他查询中看到这些查询。
SELECT
*
FROM table_1
RIGHT OUTER JOIN table_2
INNER JOIN table_3
ON table_2.some_id = table_3.some_id
RIGHT OUTER JOIN table_4
ON table_3.some_id = table_4.some_id
LEFT OUTER JOIN table_5
ON table_4.some_id = table_5.some_id
ON table_1.some_id = table_4.some_id
请不要介意这些表格是如何加入的。我只想知道该查询是如何工作的?提前谢谢。
答案 0 :(得分:3)
我认为SQL Server文档可以比MySQL更好地捕获正在发生的事情。 (Here是文档。)
正如劳伦斯观察到的那样,这是一个解析问题。您可以通过查看from
语句的语法图来了解它是什么。有一个大多数人从未想过的递归参考(包括我)。联接表具有以下语法:
<joined_table> ::=
{
<table_source> <join_type> <table_source> ON <search_condition>
| <table_source> CROSS JOIN <table_source>
| left_table_source { CROSS | OUTER } APPLY right_table_source
| [ ( ] <joined_table> [ ) ]
}
这里的关键是第一部分<table_source> <join_type> <table_source>
。好吧,猜猜看,table_source
可以是joined_table
(以及其他一些东西)。这意味着语法:
A join B join C ON <condition1> ON <condition2>
符合上面的语法并解释为:
A join (B join C on <condition1>) ON <condition2>
即表达式B join C on <condition1>
被视为“table_source”。
我的猜测是,如果SQL Server和MySQL都这样做,那么它可能是标准的一部分。但是,该标准比SQL Server的语法图更难理解。
答案 1 :(得分:2)
我认为这取决于评估右外连接的方式:
Select
*
from
a
right outer join
b
inner join
c
on b.id = c.id
on a.id = b.id;
评估为
Select
*
from
a
right outer join (
b
inner join
c
on b.id = c.id
)
on a.id = b.id;
混合左右外连接是疯狂的途径。
OP的查询似乎是由排除括号或派生表的愿望驱动的。它相当于:
Select
a.id ida,
b.id idb,
c.id idc,
d.id idd,
e.id ide
From
D
left outer join
A
on d.id = a.id
left outer join
E
on d.id = e.id
left outer join (
B
inner join
C
on b.id = c.id
)
on d.id = b.id;
<强> Example SQLFiddle 强>