簡體   English   中英

帶或不帶HAVING子句的MySQL COUNT查詢給出相同結果

[英]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.

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