2014-09-27 86 views
0

这是产品选择产品计数为每个类别中,当产品在子类别

PROD_ID  CATEG_ID 
1   2 
2   21 
3   211 
4   5 
5   51 

表结构这是类别的表格结构

CATEG_ID PARENT_CATEG_ID 
2   NULL 
5   NULL 
21   2 
211   21 
51   5 

我有困难时为每个类别选择产品数量,包括嵌套类别。 例如,2类别有1个产品,21类别有1个产品,211类别有1级的产品,并且由于类别21221是类别2的各自直接/间接祖先,2类别有3种产品。所以我需要一个查询或只是一种方式来得到这样的东西:

CATEG_ID PARENT_CATEG_ID PRODUCT_COUNT 
2   NULL    3 (including product count for categories 21 and 221) 
5   NULL    2 (including product count for category 51) 
21   2     2 (including product count for category 221) 
211   21     1 (no category ancestor, only product count for self) 
51   5     1 (no category ancestor, only product count for self) 

是只有SQL可能或我需要添加一些PHP?

+0

执行类别跟随其中获得Ÿ去除ID的最后一位家长这样漂亮的图案? – 2014-09-27 11:25:38

+0

@Gordon Linoff他们是,但是,我不能依靠它 – 2014-09-27 11:43:54

+0

然后测试从“a_horse_with_no_name”的答案,并接受并upvote它,如果正确。 – 2014-09-27 11:50:53

回答

2

下应该这样做:

with recursive cat as (
    select categ_id, 
     parent_categ_id, 
     categ_id as root_category, 
     1 as level 
    from categories 
    where parent_categ_id is null 
    union all 
    select c.categ_id, 
     c.parent_categ_id, 
     p.root_category, 
     p.level + 1 
    from categories c 
    join cat as p on p.categ_id = c.parent_categ_id 
) 
select c.categ_id, 
     p.prod_id, 
     (select count(*) from cat c2 where c2.level >= c.level and c2.root_category = c.root_category) as cnt 
from cat c 
    left join products p on p.categ_id = c.categ_id 
; 

递归查询首先构建整个目录树。它返回每个类别的根类别以及特定根类别的子树内类别的嵌套级别。该CTE本身返回此:

 
categ_id | parent_categ_id | root_category | level 
---------+-----------------+---------------+------ 
     2 |   (null) |    2 |  1 
     21 |    2 |    2 |  2 
    211 |    21 |    2 |  3 
     5 |   (null) |    5 |  1 
     51 |    5 |    5 |  2 

这随后被用于加入对产品表,并做包含在同一根类别的产品的运行总和(这是count(p.prod_id) over (partition by c.root_category order by level desc)部分)。因此,完整的查询的结果是这样的:

 
categ_id | prod_id | product_count 
---------+---------+-------------- 
     2 |  1 |    3 
     21 |  2 |    2 
    211 |  3 |    1 
     5 |  4 |    2 
     51 |  5 |    1 

SQLFiddle:http://sqlfiddle.com/#!15/d6261/15

+0

好的答案伙计!请告诉我,这是想要的行为? http://sqlfiddle.com/#!15/d6261/11它会返回每个产品行中每个根类别的产品数量 – 2014-09-27 12:33:12

+0

@IvanHanák:请参阅我的编辑 - 尽管我不认为该解决方案的性能会很好。 – 2014-09-27 13:32:50

相关问题