提问人:Patrick Szalapski 提问时间:7/28/2023 最后编辑:Dale KPatrick Szalapski 更新时间:7/28/2023 访问量:147
这个没有子查询的“嵌套 JOIN”语法是什么?
What is this "nested JOIN" syntax without a subquery called?
问:
在 SQL Server (T-SQL) 中,我当然可以 JOIN 到子查询,但我刚刚了解到我也可以 JOIN 到不是子查询的嵌套 JOIN 表达式。例如:
SELECT *
FROM dbo.Customer c
JOIN ( /* note no SELECT */
dbo.Table2 t2
JOIN dbo.Table3 t3 ON t3.t2Id = t2.Id
) ON c.t2Id = t2.Id /* note no alias */
WHERE c.CustomerId = 1234;
这个“没有子查询的嵌套 JOIN”语法叫什么,我可以在 Microsoft 文档中找到它?在联接或子查询的上下文中未提及它。
答:
括号是一个表表达式,它们意味着您肯定希望服务器在外部 JOIN 表达式之前完成嵌套的 JOIN 表达式。对于此查询,其中所有内容都是内部连接,这与以传统方式列出 JOIN 没有什么不同(只是要注意子句的编写方式):ON
SELECT *
FROM dbo.Customer c
JOIN dbo.Table2 t2 ON c.t2Id = t2.Id
JOIN dbo.Table3 t3 on t3.t2Id = t2.Id
WHERE c.CustomerId = 1234;
上面的查询将给出相同的结果,并且可以说更易于阅读和维护。
但是,可以使用括号内的表达式以比不带括号的查询更易于编写和理解的方式生成结果。OUTER JOIN
评论
JOIN ... JOIN ... ON ... ON...
ON
<joined_table>
<table_source>
不是派生表。不是子查询。不是临时表。它的作用是在逻辑上定义执行联接的顺序。它与内部连接几乎没有用处。它真正有用的地方是与外部连接一起使用时。
一个示例用例可能是“所有订单到延期交货的产品”,但中间有一个联结表。这可以编码为:left join
...
FROM Order O
LEFT JOIN (
OrderDetail OD
JOIN Product P
ON P.ProductId= OD.ProductId
AND P.IsBackOrdered = 1 -- Not proper design, but it's just an example
)
ON OD.OrderId = O.OrderId
这允许在将订单详细信息和产品行馈送到 LEFT JOIN 之前进行合并和筛选。
括号实际上是可选的,但我更喜欢包含它们以在一定程度上提高可读性(给读者一个提示,说明正在发生一些棘手的事情)。
但至于“它叫什么?我不认为它有名字。我将其视为分组联接或无序联接。这几乎就像 HP-35 及其后继者时代的 HP 计算器的反向波兰符号 (RPN)。
评论
FROM
在 Microsoft 文档中的什么位置可以找到它?
在 FROM
子句中(正如 @mustaccio 在此跨站点欺骗中指出的那样)。
您的条款是FROM
FROM dbo.Customer c
JOIN ( dbo.Table2 t2
JOIN dbo.Table3 t3
ON t3.t2Id = t2.Id )
ON c.t2Id = t2.Id
请注意的语法是joined_table
<joined_table> ::=
{
<table_source> <join_type> <table_source> ON <search_condition>
....
| [ ( ] <joined_table> [ ) ]
}
所以以下是一个有效的<joined_table>
dbo.Table2 t2
JOIN dbo.Table3 t3
ON t3.t2Id = t2.Id
上面的语法还显示了可选的括号,可以应用于 a 以产生另一个有效的括号,所以这也是一个<joined_table>
<joined_table>
( dbo.Table2 t2
JOIN dbo.Table3 t3
ON t3.t2Id = t2.Id )
而且,正如该文档页面上的语法中进一步显示的那样,也是一个有效的.<joined_table>
<table_source>
所以你只是在做
SELECT *
FROM dbo.Customer c
JOIN <joined_table>
ON c.t2Id = t2.Id
并且,在某种程度上递归地,使用 a 作为 a 来产生进一步的 .<joined_table>
<table_source>
<joined_table>
下一个:嵌套 SQL - 更快?
评论
FROM Order O LEFT JOIN (OrderDetail OD JOIN Product P ON P.P_ID = OD.P_ID AND P.IsBackOrdered) ON OD.O_ID = O.O_ID