Arn*_*lis 19 php mysql recursion
为了回答这个问题,我将给予100点奖励积分
所以我对递归有一个非常困难的问题 - 如何获得所有项目的类别和包含该父项的所有子项,并且直到最后更深入?
我有桌子:
+----+---------------+-----------------+
| id | category name | category_parent |
+----+---------------+-----------------+
| 1 | cars | 0 |
+----+---------------+-----------------+
| 2 | real estate | 0 |
+----+---------------+-----------------+
| 3 | clothes | 0 |
+----+---------------+-----------------+
| 4 | bmw | 1 |
+----+---------------+-----------------+
| 5 | audi | 1 |
+----+---------------+-----------------+
| 6 | 100 | 5 |
+----+---------------+-----------------+
| 7 | 80 | 5 |
+----+---------------+-----------------+
| 8 | A4 | 5 |
+----+---------------+-----------------+
| 9 | QUATRO | 8 |
+----+---------------+-----------------+
| 10 | TDI | 8 |
+----+---------------+-----------------+
| 11 | Black | 9 |
+----+---------------+-----------------+
| 12 | White | 9 |
+----+---------------+-----------------+
| 13 | 2 doors | 11 |
+----+---------------+-----------------+
| 14 | 5 doors | 11 |
+----+---------------+-----------------+
Run Code Online (Sandbox Code Playgroud)
我的产品表看起来像这样:
+----+---------------+-----------------+
| id | category_id | name |
+----+---------------+-----------------+
Run Code Online (Sandbox Code Playgroud)
例如,我想计算所有cars类别的项目.所以基本上我应该传递这个类别的ID,(1)并以某种方式进行递归来计算所有项目.但是我不知道如何处理它,因为那个类别的孩子可能是无限的.
所以,当我想知道那个父母计数的所有项目时,我应该做这样的事情:
1++:
4++
5++:
6++
7++
8++:
9++:
11++:
13++
14++
12++
10++
Run Code Online (Sandbox Code Playgroud)
我希望你能理解我需要什么,并给我任何可以帮助我的建议.
而且,这是我到目前为止所做的开始 - 我可以实现它,但将来我会陷入递归...所以它没有价值.
public function get_category_tree_id_list($cat_id, $list_array = FALSE)
{
if ( !$list_array ){
$items = $this->system->_getCustomTableData('categories', array(array('category_parent' => $cat_id)), 'id DESC');
$this->__tmp['id_list'] = [];
foreach ( $items as $key => $value ) {
$this->__tmp['id_list'][] = $value['id'];
}
}
}
Run Code Online (Sandbox Code Playgroud)
dav*_*ave 14
您很可能想要嵌套集.它们设置起来有点棘手,但使查询更简单.所以,与其类别的父母,你将有两列- lft和rgt.左侧和右侧基本上是类别的边界,如果项目的类别ID在这些值之间,您知道它是该类别的子级.
+----+---------------+-----+------+
| id | category name | lft | rgt |
+----+---------------+-----+------+
| 1 | cars | 1 | 24 |
+----+---------------+-----+------+
| 2 | bmw | 2 | 3 |
+----+---------------+-----+------+
| 5 | audi | 4 | 23 |
+----+---------------+-----+------+
| 6 | 100 | 5 | 6 |
+----+---------------+-----+------+
| 7 | 80 | 7 | 8 |
+----+---------------+-----+------+
| 8 | A4 | 9 | 22 |
+----+---------------+-----+------+
| 9 | TDI | 10 | 11 |
+----+---------------+-----+------+
| 10 | Quatro | 12 | 21 |
+----+---------------+-----+------+
| 11 | Black | 13 | 18 |
+----+---------------+-----+------+
| 12 | White | 19 | 20 |
+----+---------------+-----+------+
| 13 | 2 doors | 14 | 15 |
+----+---------------+-----+------+
| 14 | 5 doors | 16 | 17 |
+----+---------------+-----+------+
Run Code Online (Sandbox Code Playgroud)
然后,要获得汽车类别中的项目数量,您可以像这样超级简单地完成:
SELECT categories.name, items.id, items.category_id, items.name
FROM categories
LEFT JOIN items
ON (items.category_id BETWEEN categories.lft AND categories.rgt)
WHERE categories.category_name = 'cars'
Run Code Online (Sandbox Code Playgroud)
显然,您只需更改category_name任何类别中的项目并获取项目.
抱歉,由于某种原因,我在此处上传图片时图像已旋转,但如果您将类别绘制为圆圈,然后对线条进行编号,则可以看到左右值的值.
我只做了汽车,因为我认为你可以推断出其他类别.
所以,如果你写出这样的类别:
Cars(BMW(), Audi(100(),80(),A4(TDI(),Quatro(Black(2dr(),5dr()), White())))
Run Code Online (Sandbox Code Playgroud)
然后你可以用数字标记你的括号:
Cars[1]->(BMW[2]->()<-[3], Audi[4]->(100[5]->()<-[6],80[7]->()<-[8],A4[9]->(TDI[10]->()<-[11],Quatro[12]->(Black[13]->(2dr[14]->()<-[15], 5dr[16]->()<-[17])<-[18], White[19]->()<-[20])<-[21])<-[22])<-[23])<-[24]
Run Code Online (Sandbox Code Playgroud)
或者,如果您将其绘制为树状,则可以将其标记为这样,在此处用最大的数字标记最左边的节点,并在标记所有子节点时仅标记正确的节点:
我有一个新想法,我认为这会很好。想法是这样的:在category_parent列中,我们将插入对此节点的所有父节点的引用。
+----+----------------+----------------+ | 编号 | 类别名称 | 等级制度 | +----+----------------+----------------+ | 1 | 汽车 | 1 | +----+----------------+----------------+ | 2 | 房地产| 2 | +----+----------------+----------------+ | 3 | 衣服| 3 | +----+----------------+----------------+ | 4 | 宝马| 1-4 | 1-4 +----+----------------+----------------+ | 5 | 奥迪 | 1-5 | 1-5 +----+----------------+----------------+ | 6 | 100 | 100 1-4-6 | 1-4-6 +----+----------------+----------------+ | 7 | 80| 1-4-7 | 1-4-7 +----+----------------+----------------+ | 8 | A4| 1-4-8 | 1-4-8 +----+----------------+----------------+ | 9 | 四轮| 1-4-8-9 | 1-4-8-9 | +----+----------------+----------------+ | 10 | 10 TDI | 1-4-8-10 | 1-4-8-10 | +----+----------------+----------------+ | 11 | 11 黑色| 1-4-8-9-11 | 1-4-8-9-11 | +----+----------------+----------------+ | 12 | 12 白色| 1-4-8-9-12 | 1-4-8-9-12 | +----+----------------+----------------+ | 13 | 2 门 | 1-4-8-9-11-13 | 1-4-8-9-11-13 | +----+----------------+----------------+ | 14 | 14 5 门 | 1-4-8-9-11-14 | 1-4-8-9-11-14 | +----+----------------+----------------+
如果您查看我更新的表格,您会发现每条记录都有与其父项的链接,不仅是直接记录,而且还包括所有父项。对于这项工作,我做了一些修改以插入为:
Insert into table_name (category_name, hierarchy) values ('new_name', (concat(parent_hierarch, '-', (SELECT Auto_increment FROM information_schema.tables WHERE table_name='table_name'))))
Run Code Online (Sandbox Code Playgroud)
现在让我们进行您想要的查询:
1- 汽车的所有子类别:
select * from table_name where hierarchy like '1-%'
Run Code Online (Sandbox Code Playgroud)
2-如果您需要黑色的所有父级,您只需输入:
select * from table_name where hierarchy = '1-4-8-9' or hierarchy = '1-4-8' or hierarchy = '1-4' or hierarchy = '1'
Run Code Online (Sandbox Code Playgroud)
(您可以从 php 构建该查询,在“-”字符处分割层次结构字段)
3- 查看所有类别,包括级别和直接父级:
select *, SUBSTR(hierarchy, 1, (LENGTH(hierarchy) - LENGTH(id) - 1)) as parent, LENGTH(hierarchy) - LENGTH(REPLACE(hierarchy, '-', '')) as level From table_name
Run Code Online (Sandbox Code Playgroud)
+----+----------------+-----------------+------------------------ -+--------+ | 编号 | 类别名称 | 等级制度 | 家长 | 水平| +----+----------------+-----------------+------------------------ -+--------+ | 1 | 汽车 | 1 | | 0 | +----+----------------+-----------------+------------------------ -+--------+ | 2 | 房地产| 2 | | 0 | +----+----------------+-----------------+------------------------ -+--------+ | 3 | 衣服| 3 | | 0 | +----+----------------+-----------------+------------------------ -+--------+ | 4 | 宝马| 1-4 | 1-4 1 | 1 | +----+----------------+-----------------+------------------------ -+--------+ | 5 | 奥迪 | 1-5 | 1-5 1 | 1 | +----+----------------+-----------------+------------------------ -+--------+ | 6 | 100 | 100 1-4-6 | 1-4-6 1-4 | 1-4 2 | +----+----------------+-----------------+------------------------ -+--------+ | 7 | 80| 1-4-7 | 1-4-7 1-4 | 1-4 2 | +----+----------------+-----------------+------------------------ -+--------+ | 8 | A4| 1-4-8 | 1-4-8 1-4 | 1-4 2 | +----+----------------+-----------------+------------------------ -+--------+ | 9 | 四轮| 1-4-8-9 | 1-4-8-9 | 1-4-8 | 1-4-8 3 | +----+----------------+-----------------+------------------------ -+--------+ | 10 | 10 TDI | 1-4-8-10 | 1-4-8-10 | 1-4-8 | 1-4-8 3 | +----+----------------+-----------------+------------------------ -+--------+ | 11 | 11 黑色| 1-4-8-9-11 | 1-4-8-9-11 | 1-4-8-9 | 1-4-8-9 | 4 | +----+----------------+-----------------+------------------------ -+--------+ | 12 | 12 白色| 1-4-8-9-12 | 1-4-8-9-12 | 1-4-8-9 | 1-4-8-9 | 4 | +----+----------------+-----------------+------------------------ -+--------+ | 13 | 2 门 | 1-4-8-9-11-13 |1-4-8-9-11 | 5 | +----+----------------+-----------------+------------------------ -+--------+ | 14 | 14 5 门 | 1-4-8-9-11-14 |1-4-8-9-11 | 5 | +----+----------------+-----------------+------------------------ -+--------+
这是一个新想法,需要一些改进。我希望你能从中受益。