MySQL:计算属于活跃类别(以及可选的活跃子类别)的活跃产品

MySQL: Counting active products that belong to active categories (and optionally to active subcategories)

我正在使用 MySQL 5.6。我需要获取类别列表,其中包含产品 count 列。到目前为止,这是一项非常简单和微不足道的任务。这是它变得有点复杂的地方:

因此,查询应该 return 包含产品数量的类别列表,满足这些要求:

这是我当前的查询:

SELECT store_cat.id_cat AS id_cat, 
       store_cat.name AS name, 
       COUNT(DISTINCT store_product.id_product) AS q 
FROM   store_cat 
       LEFT JOIN store_product 
              ON store_product.id_cat = store_cat.id_cat 
                 AND store_product.flg_public = 1 
       LEFT JOIN store_subcat 
              ON store_product.id_subcat = store_subcat.id_subcat 
                 AND store_subcat.flg_public = 1 
WHERE  store_cat.flg_public = 1 
GROUP  BY store_cat.id_cat 

我添加了一个 sqlfiddle:http://sqlfiddle.com/#!9/43461b/1

在这个例子中:

衣服 类别在数量栏中 returning 4...但它应该是 3。以下是结果应显示的内容(红色变化):

有什么想法吗?谢谢!

你的问题是,因为你 LEFT JOINstore_subcat,甚至子类别 flg_public = 0 的产品也会包含在输出行中(尝试删除 GROUP BY并更改为 SELECT * 并且您会看到 Pantalon Flash 在输出行中,即使它来自 store_subcat 的字段都是 NULL 因为它失败了 flg_public = 1加入条件)。要解决此问题,您需要添加一项检查,以确保 store_product.id_subcatNULL,或者 store_subcat.id_subcat 不是 NULL(当产品具有具有 flg_public = 1 的子类别。更新后的查询:

SELECT store_cat.id_cat AS id_cat, 
       store_cat.name AS name, 
       COUNT(DISTINCT store_product.id_product) AS q 
FROM store_cat 
LEFT JOIN store_product ON store_product.id_cat = store_cat.id_cat 
                       AND store_product.flg_public = 1 
LEFT JOIN store_subcat ON store_product.id_subcat = store_subcat.id_subcat 
                      AND store_subcat.flg_public = 1 
WHERE store_cat.flg_public = 1 
  AND (store_product.id_subcat IS NULL OR store_subcat.id_subcat IS NOT NULL)
GROUP BY store_cat.id_cat 

输出:

id_cat  name        q
1       Clothes     3
2       Accesories  1
3       Snacks      2
4       Other       0
6       Furniture   0
7       Bags        0
9       Pencils     1
10      Medicines   0
11      Candy       0

Demo on SQLFiddle

请注意,Snacks 的正确计数实际上是 2,而不是 3。在 4 种零食中,Cookie wrappersflg_public = 0,因此不应包括在内,Pan de espárragosid_subcat = 1 而那个 subcat 有 flg_public = 0 所以它也不应该被包括在内。所以在 4 种零食中,应该只包括 2 种。

SELECT store_cat.id_cat AS id_cat, 
       store_cat.name AS name, 
       COUNT(DISTINCT store_product.id_product) AS q 
FROM   store_cat 
       LEFT JOIN store_product 
              ON store_product.id_cat = store_cat.id_cat 
--                 AND store_product.flg_public = 1 
       LEFT JOIN store_subcat 
              ON store_product.id_subcat = store_subcat.id_subcat 
--                 AND store_subcat.flg_public = 1 
WHERE  store_cat.flg_public = 1 
  AND COALESCE(store_subcat.flg_public, 1)
GROUP  BY store_cat.id_cat, store_cat.name ;

fiddle

在 fiddle 中评论了最少的解释。