订单表:
+----------------+
| Field |
+----------------+
| orderNumber |
| customerNumber |
+----------------+
订单明细表:
+-----------------+
| 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
)应该排除那些其他行。
我可以将
o.orderNumber = 10123
添加到 WHERE 子句中,这可以解决问题,但当包含在 ON 子句中时,它应该按预期工作。因为如果 o.orderNumber IS NOT 10123,则条件将返回 false,因此应从结果集中排除。
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;
这将带来给定编号的所有订单以及相应的订单详细信息。如果没有订单详细信息,您仍然可以获得给定编号的订单行。如果该数字没有顺序,则结果集为空。
“LEFT JOIN 子句允许您从多个表中查询数据。它返回左表中的所有行以及右表中的匹配行。如果在右表中找不到匹配行,则使用 NULL。” (https://www.sqlservertutorial.net/sql-server-basics/sql-server-left-join/)。因此,对于“ON”条件确实没有太多期望。对于 LEFT JOIN,它们仅涉及第二个表。我建议作者更好地了解 JOIN 的种类
如果您希望
JOIN
过滤第二个表中不匹配的结果,请使用 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
子句中的单个表上更“传统”。
简短的故事,您正在请求
orders
表中的所有记录。仅当您有匹配的 orderdetails
并且 orderNumber
为 orderNumber
时,您的 join 子句才会从 10123
获取数据,但您仍然会从 orders
获取所有记录。
如果您只想在
orders
为 orderNumber
时从 10123
获取记录,则应在 orders
表上使用条件。执行此操作的常见方法是使用 WHERE
子句。
使用
LEFT JOIN
时,您将从连接表中获取匹配的记录(基于条件),但您仍将从 LEFT 表中获取所有记录。
这应该有效。
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;