MySQL:计算属于有效类别(并可选地属于有效子类别)的有效产品

问题描述 投票:0回答:2

我正在使用MySQL 5.6。我需要获取带有产品count列的类别列表。到目前为止,这是一个非常简单而琐碎的任务。这有点复杂:

  • 产品具有类别,也可以具有子类别(可选)。
  • 类别子类别产品可以处于活动状态(flg_public=1)或被禁用(flg_public=NULL)。

因此,查询应返回满足这些要求的带有产品数量的类别列表:

  • 如果禁用了类别,则它一定不能出现在列表中。
  • 如果禁用了类别的子类别,则不应考虑该子类别内的任何产品作为相应类别的产品计数。

这是我当前的查询:

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

在此示例中:

  • 子类别裤子属于类别衣服
  • 子类别裤子 id_subcat=6已被flg_public=0禁用
  • 子类别裤子仅具有1个活跃的产品,但是由于子类别已被禁用,因此count查询中不应考虑这1个产品。
  • 如您所见,有4种产品使用id_cat=1,但是其中一种产品是Pantalon Flash id_product=47,它属于被禁用的子类别Pant id_subcat=6但仍在考虑中 ...

Clothes类别在数量列中返回4 ...,但应为3。结果显示如下(红色更改):

enter image description here

有什么想法吗?谢谢!

mysql sql count left-join mysql-5.6
2个回答
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

最少的解释置入小提琴。


2
投票

您的问题是,因为您是LEFT JOINstore_subcat,所以即使包含具有flg_public = 0子类别的产品也会包含在输出行中(尝试删除GROUP BY并更改为SELECT *,您会看到即使Pantalon Flash中的字段全部为store_subcat,但NULL仍在输出行中,因为它未通过flg_public = 1连接条件)。要解决此问题,您需要添加一个检查,以确保store_product.id_subcatNULLstore_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 wrappers具有flg_public = 0,因此不应包括在内,Pan de espárragos具有id_subcat = 1,并且子目录具有[ C0],因此也不应该包含在内。因此,在4种小吃中,应仅包含2种。

© www.soinside.com 2019 - 2024. All rights reserved.