我的查询用于检索客户订购和退回的商品清单。我对上次加入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 Result:
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 Result:
P_id Pp_id P_name i_qty r_qty
P000001 P000001 Item 1 15 1
Expected Result:
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 ..
答案 0 :(得分:2)
a LEFT JOIN b
完全相同..(a
将始终存在,其中b
可能为空)
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
,正确的部分将使用CASE WHEN
{ {1}}部分,例如:
SELECT
sql Fiddle的结果
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
答案 1 :(得分:0)
这可能有效
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
WHERE ReturnCustomer.status >= 20
答案 2 :(得分:0)
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
LEFT JOIN detailRC ON detailRC.sur_key = detailSO.sur_key
LEFT JOIN ReturnCustomer ON ReturnCustomer.id = detailRC.rc_id
where
ReturnCustomer.status >= 20
AND SalesOrder.status >= 20
答案 3 :(得分:0)
我怀疑这是评估NULL值的方式。尝试在ON子句中使用ISNULL:
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 ISNULL(ReturnCustomer.status, 0) >= 20
答案 4 :(得分:0)
使用嵌套查询为您提供所需的结果
SELECT temp.* from (
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
LEFT JOIN detailRC
ON detailRC.sur_key = detailSO.sur_key
LEFT JOIN ReturnCustomer
ON ReturnCustomer.id = detailRC.rc_id
) as temp
WHERE temp .status >= 20