计算树中子级别类别的值,并应用于PHP或MYSQL中的所有父级

时间:2015-07-10 11:35:00

标签: php mysql

我在mysql中为电子商务网站提供了最多5级别的分类树,树是基于parent_id方法生成的,我还在表总计中有一列来显示每个类别中的产品数量。

我被要求提前一周实现一项新功能,以显示每个parent_id类别中的产品数量,如下面显示PHP数组中数据库表值的示例。

preview of desired results

原始数组如下:

$array = [
'101' => [
    'total' => null,
    'array' => [
        '102' => 4,
        '103' => 24,
        '104' => [
            'total' => null,
            'array' => [
                '105' => 9,
                '106' => [
                    'total' => null,
                    'array' => [
                        '107' => 2,
                        '108' => 3
                    ]
                ],
                '109' => [
                    'total' => null,
                    'array' => [
                        '110' => 2,
                        '111' => 3
                    ]
                ]
            ],
        ],
        '112' => [
            'total' => null,
            'array' => [
                '113' => 2,
                '114' => 3
            ]
        ]
    ]
],
'115' => [
    'total' => null,
    'array' => [
        '116' => 2,
        '117' => 3
    ]
]];

本周我尝试了很多方法,没有任何方法可以解决,但是也没有任何帮助,我仍然不确定如何从每个最高的树级向后递归递归。

您在数据库中计算和更新这些值的方法是什么?

以下是mysql表结构和虚拟数据:

  

INSERT INTO dummy_categories(id,parent_id,total)VALUES       (101,0,NULL),(102,101,4),(103,101,24),(104101,NULL),       (105,104,9),(106104,NULL),(107,106,2),(108,106,3),       (109104,NULL),(110,109,2),(111,109,3),(112101,NULL),       (113,112,2),(114,112,3),(115,0,NULL),(116,115,2),(117,115,3);

1 个答案:

答案 0 :(得分:0)

以下是我对所有父母总结儿童总数的方法:

class CountChildValuesToParents {
    private $_nodes;
    private $_node;
    private $_parentId;
    private $_data;

    public function updateData($data) {
        $this->_data = [];
        $this->_node = 0;
        $this->_nodes = [];
        $data = $this->buildTree($data);
        $this->update($data, $data[0]);
        $this->emptyNodes();
        foreach ($this->_data as $id => $total) {
            UPDATE dummy_categories SET total=$total WHERE id=$id
        }

    }
    private function buildTree($data) {
        $cats = [];
        foreach ($data as $v) {
            $cats[$v['parent_id']][$v['id']] = $v;
        }
        return $cats;
    }
    private function update(&$p, $childs) {
        foreach ($childs as $id => $v) {
            if (isset($p[$id])) {
                if (!$v['parent_id']) {
                    $this->emptyNodes();
                } elseif ($v['parent_id'] != $this->_parentId) {
                    $this->emptyNode($v['parent_id']);
                }
                $this->_parentId = $id;
                $this->_nodes = [$id => 0] + $this->_nodes;
                $this->update($p, $p[$id]);
            } elseif (isset($v['total'])) {
                $this->updateNodes((int)$v['total']);
            }
        }
    }
    private function updateNodes($value) {
        foreach ($this->_nodes as $id => $v) {
            $this->_nodes[$id] += $value;
        }
    }
    private function emptyNode($parentId) {
        if (!isset($this->_nodes[$parentId])) {
            die('ERROR: Node in _nodes not exist.');
        }

        for ($i = 0; $i < count($this->_nodes); $i++) {
            $key = key($this->_nodes);
            if ($key == $parentId) {
                return;
            }

            if (isset($this->_data[$key])) {
                die('ERROR: Node in _data already exists.');
            }
            $this->_data[$key] = $this->_nodes[$key];
            unset($this->_nodes[$key]);
        }
    }
    private function emptyAllNodes() {
        foreach ($this->_nodes as $k => $v) {
            if (isset($this->_data[$k])) {
                die('ERROR: Node in _data already exists.');
            }
            $this->_data[$k] = $v;
        }
        $this->_nodes = [];
    }
}