我遇到涉及COUNT和HAVING子句的SQL查询问题。 目的是得到所有有库存但也没有被挑选的产品的数量。为另一个客户,因此HAVING条款。
但是,当在下面的查询结尾处使用和不使用HAVING子句运行查询时,我得到与结果相同的COUNT。
为了确保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
我不知道我的查询出错了。请帮助。感谢。
答案 0 :(得分:0)
我认为你不想要having
条款。您的查询只返回一行。该having
子句可能使其返回零行而不是一行。并且,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标准函数。)
答案 1 :(得分:0)
我认为问题在于您要混合所有要检查的数量。
您的查询似乎是在尝试查找实际库存数量不等于各种状态数量总和的产品数量。
麻烦的是,您正在整理所有库存量并选择所有产品的数量。因此,如果任何单个产品不匹配,它将反映在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。