为什么 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
并且 orderNumber
是 10123
时,你的连接子句才会从 orderdetails
获取数据,但你仍然会从 [= 获取所有记录11=].
如果您只想在 orderNumber
为 10123
时从 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 上更“传统”。
查询 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
并且 orderNumber
是 10123
时,你的连接子句才会从 orderdetails
获取数据,但你仍然会从 [= 获取所有记录11=].
如果您只想在 orderNumber
为 10123
时从 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 上更“传统”。