下面的查询用于检索客户已订购并退回的商品列表。我对最后一个连接 ReturnCustomer
感到困惑,我希望查询返回 status = 20
的数据,否则返回 NULL
。以下是我的查询:
SELECT Product.id AS product_id, Product.supplier_product_id AS vip_id, Product.name AS product_name, detailSO.qty, detailRC.return_qty
FROM Product
RIGHT JOIN detailSO ON detailSO.product_id = Product.id
RIGHT JOIN SalesOrder ON SalesOrder.id = detailSO.so_id AND SalesOrder.status >= 20
LEFT JOIN detailRC ON detailRC.sur_key = detailSO.sur_key
LEFT JOIN ReturnCustomer ON ReturnCustomer.id = detailRC.rc_id AND ReturnCustomer.status >= 20
如果我使用LEFT JOIN
,它不会考虑ReturnCustomer.status >= 20
,因为它返回所有数据。另一方面,如果我使用 RIGHT JOIN
,它只会返回 ReturnCustomer.status >= 20
的数据,
LEFT JOIN 结果:
P_id Pp_id P_name i_qty r_qty
P000001 P000001 Item 1 15 1
P000001 P000001 Item 1 5 1
P000002 P000002 Item 2 5 NULL
RIGHT JOIN 结果:
P_id Pp_id P_name i_qty r_qty
P000001 P000001 Item 1 15 1
预期结果:
P_id Pp_id P_name i_qty r_qty
P000001 P000001 Item 1 15 1
P000001 P000001 Item 1 5 NULL <-- null since it comes from ReturnCustomer with status = 0
P000002 P000002 Item 2 5 NULL
我知道也许我可以使用嵌套查询来解决这个问题,希望你们能为我提供更好的解决方案。提前致谢
更新: 这是我的简化问题sqlfiddle ..
最佳答案
a LEFT JOIN b
的工作原理与此完全相同..(a
将始终存在,其中 b
可能为 null)
ON
仅适用于删除 b
,其中 a
不会受到影响。
WHERE
通过删除行来工作
所以当
A have 1,2,3
B have 1,2
C have 1,3
当这三个人加入时,例如:
SELECT *
FROM A
LEFT JOIN B ON A.x = B.x
LEFT JOIN C ON B.x = C.x
它会给出:
A B C
1 1 1
2 2
3
如果第二个 LEFT JOIN
连接到 A
,例如:
SELECT *
FROM A
LEFT JOIN B ON A.x = B.x
LEFT JOIN C ON A.x = C.x
它会给出:
A B C
1 1 1
2 2
3 3
最后一个 ON
上的任何更多条件都不会删除 B 部分,因为它之前已经加入,WHERE
部分上的任何条件都将删除整行。
就您而言,如果您想隐藏 B
部分,则不应使用 ON
或 WHERE
,正确的应该是在SELECT
部分使用CASE WHEN
,例如:
SELECT detailSO.product_id
, detailSO.qty
, CASE WHEN RC.id IS NULL THEN NULL ELSE detailRC.qty END AS x
FROM SO
LEFT JOIN detailSO ON detailSO.so_id = SO.id
LEFT JOIN detailRC ON detailRC.sur_key = detailSO.sur_key
LEFT JOIN RC ON RC.id = detailRC.rc_id AND RC.status >= 20
WHERE SO.status >= 20
sql Fiddle 的结果
product_id qty x
P00001 15 1
P00001 5 (null)
P00002 5 (null)
关于mysql - LEFT JOIN 不考虑 ON 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29769003/