在 MySQL 关系 table 中获取给定父节点的所有子节点(及其子节点)
Getting all the children (and their children) of a given parent node in a MySQL relational table
我有一个 table 这样的:
child: parent:
0003 0003
20010 0003
15003 0003
20013 20013
1234 20013
0003 20013
我正在寻找 select 给定父级的子树的查询,包括每个子级的级别,即如果给定的父级是“20013”,则输出必须是:
child: level:
[1234, 1]
[0003, 1]
[20010, 2]
[15003, 2]
重要细节我不能使用 cte 查询所以我很乐意使用标准查询的解决方案
附上 NODEJS 中的代码,它给我带来了我只需要在 mysql 过程中执行此操作的结果:
async function getCldLvl(DB, item, sons, level = 0, treetype) {
level++;
let ele1;
if (treetype)
ele1 = await myq(`use ??; SELECT * FROM trees WHERE TreeType=? AND ParentKey=?;`, [DB, treetype, item]);
else
ele1 = await myq(`use ??; SELECT * FROM trees WHERE ParentKey=? AND ItemKey!=ParentKey;`, [DB, item]);
const elements = ele1[1];
if (elements.length != 0) {
let p = [];
for (let index = 0; index < elements.length; index++) {
const e = elements[index];
if (e.ItemKey != e.ParentKey) {
sons.values.push({"ItemKey":e.ItemKey, "Quantity":e.Quantity, "Level":level});
p.push(getCldLvl(DB, e.ItemKey, sons, level, e.TreeType));
}
}
await Promise.all(p);
}
}
let sons = { values: [] };
await getCldLvl(DB, "apple", sons);
console.log(sons);
谢谢:)
CREATE PROCEDURE get_childs ()
BEGIN
CREATE TABLE get_childs_tmp(id INT UNIQUE, level INT) ENGINE = Memory;
INSERT INTO get_childs_tmp SELECT child, 0 FROM test WHERE child = parent;
REPEAT
INSERT IGNORE INTO get_childs_tmp
SELECT test.child, get_childs_tmp.level + 1
FROM get_childs_tmp
JOIN test ON test.parent = get_childs_tmp.id;
UNTIL !ROW_COUNT() END REPEAT;
SELECT * FROM get_childs_tmp WHERE level > 0;
DROP TABLE get_childs_tmp;
END
https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=c5933bfa05414cd68c91c318a727ed6f
我有一个 table 这样的:
child: parent:
0003 0003
20010 0003
15003 0003
20013 20013
1234 20013
0003 20013
我正在寻找 select 给定父级的子树的查询,包括每个子级的级别,即如果给定的父级是“20013”,则输出必须是:
child: level:
[1234, 1]
[0003, 1]
[20010, 2]
[15003, 2]
重要细节我不能使用 cte 查询所以我很乐意使用标准查询的解决方案
附上 NODEJS 中的代码,它给我带来了我只需要在 mysql 过程中执行此操作的结果:
async function getCldLvl(DB, item, sons, level = 0, treetype) {
level++;
let ele1;
if (treetype)
ele1 = await myq(`use ??; SELECT * FROM trees WHERE TreeType=? AND ParentKey=?;`, [DB, treetype, item]);
else
ele1 = await myq(`use ??; SELECT * FROM trees WHERE ParentKey=? AND ItemKey!=ParentKey;`, [DB, item]);
const elements = ele1[1];
if (elements.length != 0) {
let p = [];
for (let index = 0; index < elements.length; index++) {
const e = elements[index];
if (e.ItemKey != e.ParentKey) {
sons.values.push({"ItemKey":e.ItemKey, "Quantity":e.Quantity, "Level":level});
p.push(getCldLvl(DB, e.ItemKey, sons, level, e.TreeType));
}
}
await Promise.all(p);
}
}
let sons = { values: [] };
await getCldLvl(DB, "apple", sons);
console.log(sons);
谢谢:)
CREATE PROCEDURE get_childs ()
BEGIN
CREATE TABLE get_childs_tmp(id INT UNIQUE, level INT) ENGINE = Memory;
INSERT INTO get_childs_tmp SELECT child, 0 FROM test WHERE child = parent;
REPEAT
INSERT IGNORE INTO get_childs_tmp
SELECT test.child, get_childs_tmp.level + 1
FROM get_childs_tmp
JOIN test ON test.parent = get_childs_tmp.id;
UNTIL !ROW_COUNT() END REPEAT;
SELECT * FROM get_childs_tmp WHERE level > 0;
DROP TABLE get_childs_tmp;
END
https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=c5933bfa05414cd68c91c318a727ed6f