2013-10-24 125 views
0

我有具有以下结构的表。根据子节点的数量获取父节点的计数

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 

我需要得到每个类别的AD计数。而我使用下面的查询

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连接,因此任何帮助将不胜感激。

回答

1

使用UNION将项目从AD_TABLE与子类别从CAT_TABLE

结合
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 

SQLFIDDLE

有关SQL管理分层数据的详细建议,请参阅here

请注意,我的查询只计算类别的直接子代,而不是后代叶节点。使用该页面的术语,您的模式是邻接列表模型,并且很难在SQL中处理多个级别 - 它没有循环或递归。如果您转换为嵌套式模型,他会显示如何使用简单查询对所有终端节点进行计数。

+0

感谢这似乎工作。但我有两个问题。而不是COUNT(*)我可以使用COUNT(c.ID),我在你的小提琴中检查并产生了相同的结果。因为我听说一些说法(*)比使用单个字段更昂贵。我需要通过'AD_TABLE'.'TYPE' = 0来过滤这些计数。你能否提一下在哪里也包括这个。 – codeGEN

+0

'COUNT(x)'计算'x'的所有非空值,所以它必须检查每一行。 'COUNT(*)'只是对行进行计数,而不检查是否为空。 – Barmar

+0

我已经添加了'AD_TABLE.TYPE = 0'检查。但是您的示例数据没有任何匹配的内容。 – Barmar