为什么 Mysql 的左连接条件没有得到满足?

Why is Mysql's left join condition not being honoured?

查询 return 出乎意料的结果:为什么?

订单table:

+----------------+
| Field          |
+----------------+
| orderNumber    |
| customerNumber |
+----------------+

订单详情Table:

+-----------------+
| Field           |
+-----------------+
| orderNumber     |
| productCode     |
+-----------------+

考虑以下查询:

SELECT 
    o.orderNumber, 
    o.customerNumber, 
    d.orderNumber,
    d.productCode
FROM
    orders o
LEFT JOIN orderdetails d 
    ON ((o.orderNumber = d.orderNumber) AND (o.orderNumber = 10123)) ;

结果如下:

我希望看到 orderNumber 仅为 10123 的行

为什么我们看到包含其他订单号?我会认为连接的条件(即 o.orderNumber = 10123)应该排除那些其他行?这对我来说真的很怪异,而且结果出乎意料:非常感谢任何关于正在发生的事情的澄清。

更新 - 将条件添加到 WHERE 子句

是的,我可以将 o.orderNumber = 10123 添加到 WHERE 子句中,这将解决问题,但我担心的是它应该 仍能按预期工作 包含在 ON 子句中,不是吗?为什么?因为如果 o.orderNumber 不是 10123,条件将 return 为假,因此应该从结果集中排除?

更新:可重现的例子:

这里是 mysql 数据库:https://sp.mysqltutorial.org/wp-content/uploads/2018/03/mysqlsampledatabase.zip

这是一个在线版本,您可以在其中输入命令:https://www.mysqltutorial.org/tryit/

谢谢!

如果您想过滤给定订单号的结果集,您需要在 WHERE 子句中设置该条件:

SELECT ...
FROM orders o
LEFT JOIN orderdetails d ON d.orderNumber = o.orderNumber
WHERE o.orderNumber = 10123;

这会带来给定号码的所有订单,以及相应的订单详细信息。如果没有订单详细信息,您仍会获得给定编号的订单行。如果该号码没有订单,则结果集为空。

短篇小说,您正在请求 orders table 中的所有记录。只有当你有匹配的 orderNumber 并且 orderNumber10123 时,你的连接子句才会从 orderdetails 获取数据,但你仍然会从 [= 获取所有记录11=].

如果您只想在 orderNumber10123 时从 orders 获取记录,您应该在 orders table 上使用条件].执行此操作的常用方法是使用 WHERE 子句。

当使用 LEFT JOIN 时,您将从加入的 table 中获得匹配的记录(基于条件),但您仍然会从 LEFT[=32 中获得所有记录=] table.

这应该有效。

SELECT 
    o.orderNumber, 
    o.customerNumber, 
    d.orderNumber,
    d.productCode
FROM
    orders o
LEFT JOIN orderdetails d 
    ON (o.orderNumber = d.orderNumber) 
WHERE o.orderNumber = 10123;

"LEFT JOIN 子句允许您从多个 table 中查询数据。它 returns 左边的所有行 table 和右边的匹配行 table。如果在右侧 table 中没有找到匹配的行,则使用 NULL。" (https://www.sqlservertutorial.net/sql-server-basics/sql-server-left-join/)。因此,确实对“ON”条件没有太多期望。对于 LEFT JOIN,它们只是关于第二个 table。我建议作者更好地了解 JOIN 的种类

如果您希望 JOIN 过滤第二个 table 中不匹配的结果,则使用 inner 连接:

SELECT o.orderNumber, o.customerNumber, d.orderNumber, d.productCode
FROM orders o JOIN
     orderdetails d 
     ON o.orderNumber = d.orderNumber 
WHERE o.orderNumber = 10123;

当您想要包含不匹配的行时使用外部联接。

orderNumber 上的过滤可以在 ON 子句或 WHERE 子句中——它们等同于 inner 连接.但是,我认为将这种过滤放在 WHERE 子句中的单个 table 上更“传统”。