为啥这种“嵌套连接”适用于 PDO 而不适用于 MySql cli?
Posted
技术标签:
【中文标题】为啥这种“嵌套连接”适用于 PDO 而不适用于 MySql cli?【英文标题】:Why does this "nested join" works with PDO but not with MySql cli?为什么这种“嵌套连接”适用于 PDO 而不适用于 MySql cli? 【发布时间】:2019-01-08 15:11:54 【问题描述】:我不明白为什么这个查询有效以及它的实际含义。应该注意的是,这个查询在使用 PDO 时有效,但不能通过 mysql cli 甚至 phpmyadmin。
SELECT table1.something, table2.something
FROM someTable
LEFT JOIN table 1
INNER JOIN table2
ON table2.table1_id = table1.id
ON table1.account_id = someTable.account_id
没有抛出错误,更奇怪的是,我实际上得到的结果与查询应该做的事情是一致的。
【问题讨论】:
SQL 查询永远不会以LEFT JOIN
开头。请向我们展示您正在运行的实际完整查询。
加入...开启...加入...开启
如果这是整个查询,它不会在我知道的任何环境中工作。因为您声称它在某处有效,所以我将您的问题解释为关于 FROM
子句的子集。你应该澄清一下。
根据您的要求更改查询。我已经为您省去了其他连接和选择。
【参考方案1】:
这是有效的 SQL 语法,假设您刚刚从 FROM
子句中获取了一个 sn-p。解释为:
SELECT table1.something, table2.something
FROM someTable
LEFT JOIN
(table1 INNER JOIN
table2 bbm
ON table2.table1_id = table1.id
)
ON table1.account_id = table2.account_id
也就是说,这真的很神秘,因为别名将table2
重命名为bbm
,这并没有被使用。 ON
条件仅指较早的表。结果是CROSS JOIN
的某种奇怪形式。
以这种方式嵌套JOIN
s 应该——在我看来——仅仅被视为一种娱乐。不要嵌套JOIN
s。在下一个表/子查询引用之前,每个 JOIN
后面都应该有它自己的 ON
子句。嵌套连接使代码更难理解。它可能会引入错误(我认为在这种情况下会发生)。也可能存在一些微妙的边缘情况,很难弄清楚发生了什么。
【讨论】:
这在 MySQL 中真的有效吗?如果没有选择列表,任何 API 如何工作? @TimBiegeleisen,很久以前,SQL 标准实际上允许类似于上面的查询,即tablename1 join tablename2 on ...
- 没有选择列表。 (后来被删除了。)
虽然原始查询中有一个 from 。我刚刚隔离了导致查询错误的部分。现在已编辑。戈登,你能根据我的编辑你的吗?我添加了 select 和 from,最后一个 ON 子句在 someTable.account_id 而不是 table2.account_id 上。很抱歉给您带来不便。
无论如何,谢谢您的回答,当我弄清楚这是否真的是这样时,我会验证它。知道为什么这适用于 PDO 但不适用于 MySql cli 吗?这是最困扰我的事情。
当我在不修改数据的情况下使用此语法时,查询现在可以在 phmyadmin 中使用。我正在等着看是否有人知道为什么这仅在 PDO 上有效,然后再接受您的答案以获得完整的答案。【参考方案2】:
标准 SQL 中有两种用于编写多个连接的语法变体,常见的一种:
a join b on ... join c on ... join d on ...
还有一个奇怪的:
a join b join c join d on ... on ... on ...
在这两种情况下,首先处理第一个ON,这意味着奇怪的语法将最后一个ON中的第一个表和第一个ON中的最后一个表连接起来,这真的很难理解。这就是为什么几乎没有人使用它(但有些工具可能会创建它)
改变你的陌生
SELECT table1.something, table2.something
FROM someTable
LEFT JOIN table1
INNER JOIN table2 bbm
ON table2.table1_id = table1.id
ON table1.account_id = someTable.account_id
在第一次加入后将最后一个 ON 移到共同点:
SELECT table1.something, table2.something
FROM someTable
LEFT JOIN table1
ON table1.account_id = someTable.account_id
INNER JOIN table2 bbm
ON table2.table1_id = table1.id
【讨论】:
以上是关于为啥这种“嵌套连接”适用于 PDO 而不适用于 MySql cli?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Laravel 中间件适用于单个路由而不适用于一组路由
为啥 viewPager 的 setCurrentItem() 适用于下一页而不适用于上一页?