В моем случае
частный случай решения проблемы, ввиду того, что таблица категорий заполняется
из файла *.xml, где категории вложены друг в друга.
Заполнив таблицу БД в том же порядке категорий как и в *.xml, я ее получаю, переворачиваю сверху вниз,
и считаю в один проход примерно следующим образом:
$res = $DBH->query("SELECT groups as id, (SELECT pid FROM cat_groups WHERE id = groups) as pid, count(groups) AS col FROM cat_prod WHERE visible = 1
AND id IN(SELECT DISTINCT prod_id FROM cat_prod_prop)
GROUP BY groups");
$res = $res->fetchAll(PDO::FETCH_ASSOC);
$res = array_reverse($res);
foreach ($res as $k => $v) {
$keys = array_keys(array_column($res, 'pid'), $v['id']);
foreach ($keys as $w) {
$res[$k]['col'] += $res[$w]['col'];
}
}
foreach ($res as $row) {
$STH = $DBH->prepare("UPDATE cat_groups SET count = :count WHERE id = :id");
$STH->bindParam(':count', $row['col']);
$STH->bindParam(':id', $row['id']);
$STH->execute();
}
Решение не универсальное и подойдет если будем работать с результатом запроса в виде
adjacency list, у которого потомки идут
последовательно, учитывая уровень вложенности.
Пример:
id;pid;count
1;0;34
2;1;11
3;1;25
4;3;12
5;3;20
6;0;97
7;6;36
8;6;25
9;0;15