Mysql 基于父节点的计数获取父节点的计数';孩子们

Mysql 基于父节点的计数获取父节点的计数';孩子们,mysql,sql,Mysql,Sql,我有以下结构的表 AD_TABLE - ID|NAME|CAT_ID|TYPE 1| car | C0101|Sale 2|bike | C0201|Want CAT_TABLE - ID |NAME |PARENT|LEVEL C0100|Vehicle |C0100 | 0 C010

我有以下结构的表

AD_TABLE -
              ID|NAME|CAT_ID|TYPE
               1| car | C0101|Sale
               2|bike | C0201|Want
CAT_TABLE -
              ID   |NAME          |PARENT|LEVEL
              C0100|Vehicle       |C0100 |    0
              C0101|Car           |C0100 |    1
              C0200|Bike/Scooters |C0100 |    1
              C0201|Bike          |C0200 |    2
              C0202|Scooter       |C0200 |    2
我需要得到每个类别的广告数量。我使用下面的查询

SELECT     `CAT_TABLE`.`ID`,`CAT_TABLE`.`NAME`,`CAT_TABLE`.`LEVEL`,`CAT_TABLE`.`PARENT`,      COUNT(`AD_TABLE`.`ID`) 
    FROM       `CAT_TABLE` 
    LEFT JOIN  `AD_TABLE` 
    ON         `AD_TABLE`.`CAT_ID`=`CAT_TABLE`.`ID`
    AND        `AD_TABLE`.`TYPE`='0'
    WHERE      (`CAT_TABLE`.`ID`='C0100' OR `CAT_TABLE`.`PARENT`='C0100')
    GROUP BY   `CAT_TABLE`.`ID`

这使得作为主要类别的车辆、自行车/滑板车计数为0。我需要这些类别来获得相应子类别的数量。例如:车辆应为汽车+自行车/滑板车的总数,自行车/滑板车的总数应为自行车+滑板车的总数。我仍在学习高级SQL联接,因此非常感谢您的帮助。

使用UNION将AD_表中的项目与CAT_表中的子类别组合起来

SELECT c.ID, c.NAME, c.LEVEL, c.PARENT, COUNT(a.ID)
FROM CAT_TABLE c
LEFT JOIN (SELECT ID, CAT_ID
           FROM AD_TABLE
           WHERE TYPE = '0'
           UNION ALL
           SELECT ID, PARENT
           FROM CAT_TABLE
           WHERE LEVEL != 0) a
ON a.CAT_ID = c.ID
GROUP BY c.ID

有关在SQL中管理分层数据的更多建议,请参阅


请注意,我的查询只计算类别的直接子级,而不计算子级叶节点。使用该页面中的术语,您的模式是邻接列表模型,很难在SQL中处理多个级别——它没有循环或递归。如果您转换为嵌套集模型,他将演示如何通过一个简单的查询来计算所有终端节点。

谢谢,这似乎是可行的。但我有两个问题。我可以使用COUNT(c.ID)来代替COUNT(*),我在你的小提琴中检查了COUNT并产生了相同的结果。因为我听到有人说(*)比使用单个字段成本更高。我需要通过
AD\u TABLE
TYPE
=0来过滤这些计数。您能否提及在何处也包含该值。
COUNT(x)
统计
x
的所有非空值,因此它必须检查每一行
COUNT(*)
只对行进行计数,不检查是否为空。我添加了
AD_TABLE.TYPE=0
check。但是您的示例数据没有与之匹配的任何内容。您的fiddle答案没有WHERE TYPE='0',这就是为什么我感到困惑的原因。sry。我以前没有注意到,但是结果生成的Scooter count为1,应该为0,因为没有类别Scooter的广告将其更改为
count(a.ID)
,因此没有子类别的类别将计为0。由于左联接,该值将为NULL。