我有一个MySQL表,如下所示:
id |
name |
parent_id |
19 |
category1 |
0 |
20 |
category2 |
19 |
21 |
category3 |
20 |
22 |
category4 |
21 |
... |
... |
... |
现在,我想有一个单一的MySQL查询,我只是提供id[例如说id=19],然后我应该得到它的所有子id[即结果应该有id '20,21,22']....
孩子们的等级尚不清楚;它可以变化....
我知道如何使用for循环…但是如何使用一个MySQL查询来实现相同的功能呢?
这是一个分类表。
SELECT id,
NAME,
parent_category
FROM (SELECT * FROM category
ORDER BY parent_category, id) products_sorted,
(SELECT @pv := '2') initialisation
WHERE FIND_IN_SET(parent_category, @pv) > 0
AND @pv := CONCAT(@pv, ',', id)
输出:
我向你提出了一个问题。这将给你递归类别与一个单一的查询:
SELECT id,NAME,'' AS subName,'' AS subsubName,'' AS subsubsubName FROM Table1 WHERE prent is NULL
UNION
SELECT b.id,a.name,b.name AS subName,'' AS subsubName,'' AS subsubsubName FROM Table1 AS a LEFT JOIN Table1 AS b ON b.prent=a.id WHERE a.prent is NULL AND b.name IS NOT NULL
UNION
SELECT c.id,a.name,b.name AS subName,c.name AS subsubName,'' AS subsubsubName FROM Table1 AS a LEFT JOIN Table1 AS b ON b.prent=a.id LEFT JOIN Table1 AS c ON c.prent=b.id WHERE a.prent is NULL AND c.name IS NOT NULL
UNION
SELECT d.id,a.name,b.name AS subName,c.name AS subsubName,d.name AS subsubsubName FROM Table1 AS a LEFT JOIN Table1 AS b ON b.prent=a.id LEFT JOIN Table1 AS c ON c.prent=b.id LEFT JOIN Table1 AS d ON d.prent=c.id WHERE a.prent is NULL AND d.name IS NOT NULL
ORDER BY NAME,subName,subsubName,subsubsubName
这是一把小提琴。
使用BlueM/tree php类在mysql中创建一个自关系表的树。
Tree和Tree\Node是PHP类,用于处理使用父ID引用分层结构的数据。一个典型的例子是关系数据库中的一个表,其中每个记录的“父”字段引用另一个记录的主键。当然,Tree不能只使用来自数据库的数据,而是使用任何数据:您提供数据,Tree使用它,而不管数据来自何处以及如何处理。阅读更多
下面是一个使用BlueM/tree的例子:
<?php
require '/path/to/vendor/autoload.php'; $db = new PDO(...); // Set up your database connection
$stm = $db->query('SELECT id, parent, title FROM tablename ORDER BY title');
$records = $stm->fetchAll(PDO::FETCH_ASSOC);
$tree = new BlueM\Tree($records);
...
如果需要快速读取速度,最好的选择是使用闭包表。闭包表为每个祖先/后代对包含一行。在你的例子中,闭包表是这样的
ancestor | descendant | depth
0 | 0 | 0
0 | 19 | 1
0 | 20 | 2
0 | 21 | 3
0 | 22 | 4
19 | 19 | 0
19 | 20 | 1
19 | 21 | 3
19 | 22 | 4
20 | 20 | 0
20 | 21 | 1
20 | 22 | 2
21 | 21 | 0
21 | 22 | 1
22 | 22 | 0
一旦有了这个表,分层查询就变得非常简单和快速。获取类别20的所有子类:
SELECT cat.* FROM categories_closure AS cl
INNER JOIN categories AS cat ON cat.id = cl.descendant
WHERE cl.ancestor = 20 AND cl.depth > 0
当然,无论何时使用这样的非规格化数据都有一个很大的缺点。您需要在类别表旁边维护闭包表。最好的方法可能是使用触发器,但是正确跟踪闭包表的插入/更新/删除有点复杂。与任何事情一样,您需要查看您的需求,并决定哪种方法最适合您。
编辑:请参阅问题:在关系数据库中存储层次数据的选项是什么?更多选项。不同的情况有不同的最佳解决方案。