[英]Trouble with LEFT OUTER JOIN
我正在嘗試按銷售數量和日期獲取產品訂單列表。 我還想顯示列表中未售出的產品,因此我嘗試首先執行子查詢,但MYSQL給出了以下消息:
操作數應包含1列
SELECT product.product_id,
product.product_brand_id,
product.product_model_id,
product.product_subcategory_id,
product.product_retail_price,
product.product_wholesale_price
FROM product
WHERE product.product_subcategory_id = $subcategory_id
AND (SELECT SUM(product_sold.product_quantity) AS product_quantity_sold,
SUM(product_sold.product_total_price) AS total_price_sold
FROM product
INNER JOIN product_sold
ON product.product_id = product_sold.product_id
INNER JOIN sales
ON sales.sales_id = product_sold.product_sales_id
WHERE sales.sales_approved = '1'
AND sales.sales_approved_time > '$start_timestamp'
AND sales.sales_approved_time < '$end_timestamp')
子查詢不起作用,因此我嘗試使用LEFT OUTER JOIN
如該查詢的另一個成員所建議:
SELECT product.product_id,
product.product_brand_id,
product.product_model_id,
product.product_subcategory_id,
product.product_retail_price,
product.product_wholesale_price,
SUM(product_sold.product_quantity) AS product_quantity_sold,
SUM(product_sold.product_total_price) AS total_price_sold
FROM product
LEFT OUTER JOIN product_sold ON product.product_id = product_sold.product_id
AND product.product_subcategory_id = $subcategory_id
LEFT OUTER JOIN sales ON sales.sales_id = product_sold.product_sales_id
WHERE sales.sales_approved = '1'
AND sales.sales_approved_time > '$start_timestamp'
AND sales.sales_approved_time < '$end_timestamp'
GROUP BY product.product_id
ORDER BY SUM(product_sold.product_quantity) DESC
但是這個關於LEFT OUTER JOIN
查詢只給出了我出售的產品列表,我想要的是還顯示該列表中沒有出售的產品。
這是使用的架構sqlfiddle.com/#!2/967ee
此查詢將起作用,要從products表中SELECT
更多列,請將它們添加到SELECT
和GROUP BY
子句中:
SELECT p.product_id
,SUM(IFNULL(ps.product_quantity,0)) AS product_quantity_sold
,SUM(IFNULL(ps.product_total_price,0)) AS total_price_sold
FROM product p
LEFT JOIN product_sold ps ON p.product_id = ps.product_id
LEFT JOIN sales s ON ps.product_sales_id = s.sales_id
WHERE p.product_subcategory_id = $subcategory_id
AND ( s.sales_id IS NULL
OR ( s.sales_approved = '1'
AND s.sales_approved_time > '$start_timestamp'
AND s.sales_approved_time < '$end_timestamp'
)
)
GROUP BY p.product_id
ORDER BY SUM(IFNULL(ps.product_quantity,0)) DESC
說明
如果您可以在WHERE
子句中使用product_sold_approved
和product_sold_approved_time
而不是sales表中的值,則此查詢將更加簡單。
您LEFT JOIN product_sold
,一個LEFT JOIN
意味着您保留了products
表中的所有記錄,並且已售出的記錄將加入到每個product_sold
記錄中。 然后,對sales
表執行相同的操作。
因此,在此階段,您有很多行是product + product_sold + sales
但您還有所有未售出的產品product + NULL + NULL
。 您需要過濾出匹配的銷售字段不符合您的條件的所有聯接記錄,但是您需要將所有未能聯接的記錄留空。
為此,您有一個WHERE子句,該子句分別處理每組記錄。 WHERE (condition A) OR (condition B)
。
條件A處理我們的未售出產品WHERE s.sales_id IS NULL
結果集包含所有無法加入銷售的記錄,而不必與其他條件匹配。
OR (sales_approved = 1 AND ... AND ...)
記錄s.sales_id不為NULL的記錄將必須通過where子句的這一部分,因此我們可以過濾掉不必要的銷售。
最后,我們得到一個結果集,其中包含沒有任何銷售的所有記錄+滿足您條件的所有product / product_sales / sales記錄。 然后,我們可以GROUP BY product_id和求和。
我的SQL中有IFNULL
,這是因為如果要對許多值求和,而其中一些可能是NULL
,則如果單個值是NULL
則SUM
的結果是NULL
。 IFNULL(column,0)
通過將任何NULL
值轉換為0
來防止這種情況。 1 + NULL = NULL
, 1 + 0 = 1
。 但是 ,在反思中,我可能不需要查詢-刪除它們,您應該會注意到更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.