首页 > 解决方案 > 仅显示具有任何产品或其子类别具有任何产品的根级别类别

问题描述

请告诉我,有2张桌子:

1 - 类别表和链接(cat2 和 cat3 以 cat1 为准)

prod_category
id|name|parent_category|
1 |cat1|       0       |
2 |cat2|       1       |
3 |cat3|       1       |
4 |cat4|       3       |
5 |cat5|       3       |
6 |cat6|       0       |
7 |cat7|       6       |
8 |cat8|       0       |
9 |cat9|       8       |
10|cat10|      9       |

2 - 产品及其类别表

products
id| name|category_id|
1 |prod1|     0     |
2 |prod2|     1     |
3 |prod3|     2     |
4 |prod4|     3     |
5 |prod5|     4     |
6 |prod6|     5     |
7 |prod7|     6     |
8 |prod8|     7     |
9 |prdo9|     8     |
10|prod10|    9     |

我在做 sql 父类循环:

$stmt = $pdo->query("SELECT * FROM prod_category WHERE parent_category='0'");
while ($row = $stmt->fetch()) {
if ($count_products_in_category > 0) {
echo $row['name'];
}
else {}
}

接下来,我需要计算这个类别是否固定在产品中(其中是否有产品)。如果没有,则取从属(子)的类别,并计算其中是否有产品,直到关系结束。如果任何类别中有产品(子类别或父类别本身),则显示$row['name'],如果没有,则不显示。

标签: phpmysqlpdo

解决方案


三个步骤

SQL

获取包含产品数量的所有类别

select c.id, c.parent, c.name, count(p.id) cnt from categories c 
left join products p on p.cat_id=c.id 
group by c.id

PDO

使用特殊的 PDO 能力返回由第一个字段索引的数组,在我们的例子中是 id

$data = $pdo->query($sql)->fetchAll(PDO::FETCH_UNIQUE);

PHP

现在对于每个类别,向上到根,就像我之前向你展示的那样

$roots = [];
foreach ($data as $cat) {
    $cnt = 0;
    do {
        $cnt += $cat['cnt'];
        $cat = $data[$cat['parent']];
    } while($cat['parent']);

    $roots[$cat['id']] = $cat;
    $roots[$cat['id']]['has_products'] ?? 0;
    $roots[$cat['id']]['has_products'] = max((bool)$cnt, $roots[$cat['id']]['has_products']);
}

它应该为您提供一个包含根类别的数组,每个类别都有一个标志,无论它是否有任何产品。

使用更通用的类别结构实现,例如物化路径,可以在一个 SQL 查询中获取所有需要的数据


推荐阅读