Php 仅显示具有任何产品或其子类别具有任何产品的根级别类别

Php 仅显示具有任何产品或其子类别具有任何产品的根级别类别,php,mysql,pdo,Php,Mysql,Pdo,请告诉我,有两张桌子: 1-类别和链接表(cat2和cat3以cat1为准) 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

请告诉我,有两张桌子:

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

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']
,如果没有,则不显示。

三个步骤

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查询中获得所有必需的数据

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查询中获得所有必需的数据

是否有最大数量的子类别级别?如果有,则可以为最大层数创建循环,如果没有,则应该这样做recursively@kiks73不幸的是,没有,它可以是10或100。是否有子类别级别的最大数量?如果有,则可以为最大层数创建循环,如果没有,则应该这样做recursively@kiks73不幸的是,它可能是10或100。PHP致命错误:未捕获PDOException:SQLSTATE[42000]:语法错误或访问冲突:1064您的SQL语法有错误;检查与您的MariaDB服务器版本相对应的手册,以了解在“where p.category=c.id group by c.id”附近使用的正确语法。当然,我忘了上面的条款了。您自己能做吗?你了解SQL连接吗?不幸的是,我是新来的。PHP致命错误:未捕获PDOException:SQLSTATE[42000]:语法错误或访问冲突:1064你的SQL语法有错误;检查与您的MariaDB服务器版本相对应的手册,以了解在“where p.category=c.id group by c.id”附近使用的正确语法。当然,我忘了上面的条款了。您自己能做吗?你了解SQL连接吗?不幸的是,我不熟悉这个。