gpt4 book ai didi

mysql - 在 mysql < 8 中获取树文件夹结构的父项和子项并且没有 CTE

转载 作者:IT老高 更新时间:2023-10-29 00:03:42 25 4
gpt4 key购买 nike

我有一个文件夹表,它通过 idparent_id 关系连接到自身:

CREATE TABLE folders (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
title nvarchar(255) NOT NULL,
parent_id int(10) unsigned DEFAULT NULL,
PRIMARY KEY (id)
);

INSERT INTO folders(id, title, parent_id) VALUES(1, 'root', null);
INSERT INTO folders(id, title, parent_id) values(2, 'one', 1);
INSERT INTO folders(id, title, parent_id) values(3, 'target', 2);
INSERT INTO folders(id, title, parent_id) values(4, 'child one', 3);
INSERT INTO folders(id, title, parent_id) values(5, 'child two', 3);
INSERT INTO folders(id, title, parent_id) values(6, 'root 2', null);
INSERT INTO folders(id, title, parent_id) values(7, 'other child one', 6);
INSERT INTO folders(id, title, parent_id) values(8, 'other child two', 6);

我想要一个返回该记录的所有父项的查询,直接返回到路由和任何子项。

因此,如果我请求包含 id=3 的文件夹,我会得到记录:1、2、3、4、5。我不知道如何找到 parent 。

MYSQL 的版本是 5.7,目前还没有升级的计划,所以遗憾的是 CTE 不是一个选项。

我创建了这个 sql fiddle

最佳答案

在您的表格设计中,IDPARENT_ID 对应于“Adjacency List Model”,用于存储一棵树。

还有另一种设计,称为“嵌套集模型”,可以更轻松地在此处执行您想要的操作。

请参阅 Mike Hillyer 撰写的这篇出色的文章,其中描述了两者: managing-hierarchical-data-in-mysql

总结:

树存储在如下表中:

CREATE TABLE nested_category (
category_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
lft INT NOT NULL,
rgt INT NOT NULL
);

查找从根到给定节点的路径(此处为“FLASH”):

SELECT parent.name
FROM nested_category AS node,
nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
AND node.name = 'FLASH'
ORDER BY parent.lft;

查找给定节点的所有子节点(此处为“可移植电子设备”):

SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
FROM nested_category AS node,
nested_category AS parent,
nested_category AS sub_parent,
(
SELECT node.name, (COUNT(parent.name) - 1) AS depth
FROM nested_category AS node,
nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
AND node.name = 'PORTABLE ELECTRONICS'
GROUP BY node.name
ORDER BY node.lft
)AS sub_tree
WHERE node.lft BETWEEN parent.lft AND parent.rgt
AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
AND sub_parent.name = sub_tree.name
GROUP BY node.name
HAVING depth <= 1
ORDER BY node.lft;

重命名为您的文件夹表后

  • TABLE nested_category -> TABLE 文件夹
  • 列 category_id -> 列 id
  • 列名 -> 列标题

解决办法是:

CREATE TABLE folders (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(20) NOT NULL,
lft INT NOT NULL,
rgt INT NOT NULL
);

INSERT INTO folders(id, title, lft, rgt) values(1, 'root', 1, 10);
INSERT INTO folders(id, title, lft, rgt) values(2, 'one', 2, 9);
INSERT INTO folders(id, title, lft, rgt) values(3, 'target', 3, 8);
INSERT INTO folders(id, title, lft, rgt) values(4, 'child one', 4, 5);
INSERT INTO folders(id, title, lft, rgt) values(5, 'child two', 6, 7);
INSERT INTO folders(id, title, lft, rgt) values(6, 'root 2', 11, 16);
INSERT INTO folders(id, title, lft, rgt) values(7, 'other child one', 12, 13);
INSERT INTO folders(id, title, lft, rgt) values(8, 'other child two', 14, 15);

目标路径:

SELECT parent.title
FROM folders AS node,
folders AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
AND node.title = 'target'
ORDER BY parent.lft;

目标 child :

SELECT node.title, (COUNT(parent.title) - (sub_tree.depth + 1)) AS depth
FROM folders AS node,
folders AS parent,
folders AS sub_parent,
(
SELECT node.title, (COUNT(parent.title) - 1) AS depth
FROM folders AS node,
folders AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
AND node.title = 'target'
GROUP BY node.title
ORDER BY node.lft
)AS sub_tree
WHERE node.lft BETWEEN parent.lft AND parent.rgt
AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
AND sub_parent.title = sub_tree.title
GROUP BY node.title
HAVING depth <= 1
ORDER BY node.lft;

sqlfiddle

要在单个查询中获取所有数据,union 应该这样做。

关于mysql - 在 mysql < 8 中获取树文件夹结构的父项和子项并且没有 CTE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55288840/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com