[英]MySQL COUNT query with or without HAVING clause giving same results
我在涉及COUNT和HAVING子句的SQL查詢中遇到問題。 目的是獲得所有有庫存但也沒有被其他客戶“揀選”的產品的數量,因此有HAVING子句。
但是,當在下面的查詢末尾同時運行帶有和不帶有HAVING子句的查詢時,結果相同。
為了確保COUNT個結果不相同,我嘗試運行查詢以檢查是否有缺貨的商品,因為所有商品都需要有缺貨才能使結果匹配,並確認肯定有缺貨的商品股票。
SELECT
COUNT(DISTINCT p.product_id)
FROM product p
LEFT JOIN product_variant pv
ON pv.product_variant_id = p.product_id
LEFT JOIN depot_product_stock dps
ON dps.product_variant_id = pv.product_variant_id
LEFT JOIN (
SELECT pii.quantity, pii.product_variant_id
FROM `picklist_item` pii
WHERE pii.STATUS IN ('not picked')
) AS pickListNotPicked
ON pickListNotPicked.product_variant_id = pv.product_variant_id
LEFT JOIN (
SELECT pii.quantity, pii.product_variant_id
FROM `picklist_item` pii
LEFT JOIN `packing` packi ON packi.picklist_id = pii.picklist_id
WHERE pii.STATUS IN ('picked')
AND pii.date_picked > NOW() - INTERVAL 2 WEEK
AND packi.picklist_id IS NULL
) AS pickListPicked
ON pickListPicked.product_variant_id = pv.product_variant_id
LEFT JOIN (
SELECT pii.quantity, pii.product_variant_id
FROM `picklist_item` pii
LEFT JOIN `packing` packi ON packi.picklist_id = pii.picklist_id
WHERE packi.`status` IN ('new', 'in progress')
) AS pickListInProgress
ON pickListInProgress.product_variant_id = pv.product_variant_id
WHERE p.deleted = 0
HAVING SUM(dps.physical_stock)
- ifnull(SUM(pickListNotPicked.quantity),0)
- ifnull(SUM(pickListPicked.quantity) ,0)
- ifnull(SUM(pickListInProgress.quantity) ,0)
> 0
我不知道查詢哪里出問題了。 請幫助。 謝謝。
我不認為您想要一個having
子句。 您的查詢僅返回一行。 該having
子句可能返回0行而不是1行。 而且, having
子句負責檢查所有產品。
也許您希望使用where
子句:
WHERE p.deleted = 0 AND
(dps.physical_stock - ifnull(pickListNotPicked.quantity, 0) -
ifnull(pickListPicked.quantity, 0)
ifnull(pickListInProgress.quantity, 0)
) > 0
請注意,我更喜歡將ifnull()
替換為coalesce()
。 (給定選項時,我通常更喜歡ANSI標准功能。)
我認為問題在於您正在混淆所有要檢查的數量。
您的查詢似乎正在嘗試查找產品的數量,其中實際庫存數量不等於處於各種狀態的數量的總和。
問題在於您要匯總所有庫存數量並為所有產品挑選數量。 因此,如果任何單個產品不匹配,它將反映在HAVING子句中的檢查中。
我認為您需要一個大的子查詢來獲取數量不匹配的所有產品ID,然后基於此進行計數。
像這樣(未經測試)。
SELECT COUNT(product_id)
FROM
(
SELECT p.product_id
FROM product p
LEFT JOIN product_variant pv
ON pv.product_variant_id = p.product_id
LEFT JOIN depot_product_stock dps
ON dps.product_variant_id = pv.product_variant_id
LEFT JOIN
(
SELECT pii.quantity, pii.product_variant_id
FROM `picklist_item` pii
WHERE pii.STATUS IN ('not picked')
) AS pickListNotPicked
ON pickListNotPicked.product_variant_id = pv.product_variant_id
LEFT JOIN
(
SELECT pii.quantity, pii.product_variant_id
FROM `picklist_item` pii
LEFT JOIN `packing` packi ON packi.picklist_id = pii.picklist_id
WHERE pii.STATUS IN ('picked')
AND pii.date_picked > NOW() - INTERVAL 2 WEEK
AND packi.picklist_id IS NULL
) AS pickListPicked
ON pickListPicked.product_variant_id = pv.product_variant_id
LEFT JOIN
(
SELECT pii.quantity, pii.product_variant_id
FROM `picklist_item` pii
LEFT JOIN `packing` packi ON packi.picklist_id = pii.picklist_id
WHERE packi.`status` IN ('new', 'in progress')
) AS pickListInProgress
ON pickListInProgress.product_variant_id = pv.product_variant_id
WHERE p.deleted = 0
GROUP BY p.product_id
HAVING SUM(dps.physical_stock)
- IFNULL(SUM(pickListNotPicked.quantity),0)
- IFNULL(SUM(pickListPicked.quantity) ,0)
- IFNULL(SUM(pickListInProgress.quantity) ,0)
> 0
) sub0
您可以像這樣刪除一些已有的子查詢:
SELECT COUNT(DISTINCT p.product_id)
FROM
(
SELECT p.product_id
FROM product p
LEFT JOIN product_variant pv
ON pv.product_variant_id = p.product_id
LEFT JOIN depot_product_stock dps
ON dps.product_variant_id = pv.product_variant_id
LEFT JOIN
(
SELECT pii.product_variant_id,
SUM(IF(pii.STATUS IN ('not picked')), quantity, 0) AS pickListNotPicked_qty,
SUM(IF(pii.STATUS IN ('picked') AND pii.date_picked > NOW() - INTERVAL 2 WEEK AND packi.picklist_id IS NULL), quantity, 0) AS pickListPicked_qty,
SUM(IF(packi.`status` IN ('new', 'in progress')), quantity, 0) AS pickListInProgress_qty
FROM `picklist_item` pii
LEFT JOIN `packing` packi ON packi.picklist_id = pii.picklist_id
GROUP BY pii.product_variant_id
) AS quantities
ON quantities.product_variant_id = pv.product_variant_id
WHERE p.deleted = 0
GROUP BY p.product_id
HAVING SUM(dps.physical_stock)
- IFNULL(SUM(pickListNotPicked_qty),0)
- IFNULL(SUM(pickListPicked_qty) ,0)
- IFNULL(SUM(pickListInProgress_qty) ,0)
) sub0
這可能會進一步清理為:
SELECT COUNT(DISTINCT p.product_id)
FROM
(
SELECT p.product_id
FROM product p
LEFT JOIN product_variant pv
ON pv.product_variant_id = p.product_id
LEFT JOIN depot_product_stock dps
ON dps.product_variant_id = pv.product_variant_id
LEFT JOIN
(
SELECT pii.product_variant_id,
SUM(quantities) AS relevant_qty
FROM `picklist_item` pii
LEFT JOIN `packing` packi ON packi.picklist_id = pii.picklist_id
WHERE pii.STATUS = 'not picked'
OR (pii.STATUS = 'picked' AND pii.date_picked > NOW() - INTERVAL 2 WEEK AND packi.picklist_id IS NULL)
OR packi.`status` IN ('new', 'in progress')
GROUP BY pii.product_variant_id
) AS quantities
ON quantities.product_variant_id = pv.product_variant_id
WHERE p.deleted = 0
GROUP BY p.product_id
HAVING SUM(dps.physical_stock)
- IFNULL(SUM(relevant_qty) ,0)
) sub0
請注意,如果我正確理解您的要求,我不太確定您的總和邏輯。 您可以選擇上周未選擇的項目。 您還計算了狀態為新的或進行中的項目,但似乎這些項目可能已經被計為已揀配/未揀配,因此對總和進行了重復計算,並確保最終總和不匹配且項目已用於產品ID的計數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.