簡體   English   中英

左外聯接故障

[英]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更多列,請將它們添加到SELECTGROUP 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_approvedproduct_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 ,則如果單個值是NULLSUM的結果是NULL IFNULL(column,0)通過將任何NULL值轉換為0來防止這種情況。 1 + NULL = NULL1 + 0 = 1 但是 ,在反思中,我可能不需要查詢-刪除它們,您應該會注意到更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM