目录
一、创建表结构和插入数据
二、查询所有子节点
三、查询所有父节点
四、查询指定节点的根节点
五、查询所有兄弟节点(同级节点)
六、获取祖先节点及其所有子节点
七、查询每个节点之间的层级关系
八、查询指定节点之间的层级关系
一、创建表结构和插入数据
CREATE TABLE `region` (
`id` VARCHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '主键',
`parent_id` VARCHAR(36) COMMENT '父键',
`name` VARCHAR(255) NOT NULL COMMENT '地区名',
`latitude` DECIMAL(10, 6) COMMENT '经度',
`longitude` DECIMAL(10, 6) COMMENT '纬度',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `region` (`parent_id`, `name`, `latitude`, `longitude`)
VALUES (NULL, '江苏省', 31.2304, 120.663);
SET @jiangsu_id = (SELECT `id` FROM `region` WHERE `name` = '江苏省');
INSERT INTO `region` (`parent_id`, `name`, `latitude`, `longitude`)
VALUES (@jiangsu_id, '苏州市', 31.2988, 120.5853);
SET @suzhou_id = (SELECT `id` FROM `region` WHERE `name` = '苏州市');
INSERT INTO `region` (`parent_id`, `name`, `latitude`, `longitude`)
VALUES (@suzhou_id, '张家港市', 31.8754, 120.5553),
(@suzhou_id, '吴中区', 31.2622, 120.6446),
(@suzhou_id, '相城区', 31.3697, 120.646),
(@suzhou_id, '吴江区', 31.1791, 120.6411);
SET @zhangjiagang_id = (SELECT `id` FROM `region` WHERE `name` = '张家港市');
SET @wuzhong_id = (SELECT `id` FROM `region` WHERE `name` = '吴中区');
SET @xiangcheng_id = (SELECT `id` FROM `region` WHERE `name` = '相城区');
SET @wujiang_id = (SELECT `id` FROM `region` WHERE `name` = '吴江区');
INSERT INTO `region` (`parent_id`, `name`, `latitude`, `longitude`)
VALUES (@zhangjiagang_id, '凤凰镇', 31.8754, 120.5553),
(@zhangjiagang_id, '塘桥镇', 31.8754, 120.5553);
INSERT INTO `region` (`parent_id`, `name`, `latitude`, `longitude`)
VALUES (@wuzhong_id, '木渎镇', 31.2622, 120.6446);
INSERT INTO `region` (`parent_id`, `name`, `latitude`, `longitude`)
VALUES (@xiangcheng_id, '黄埭镇', 31.3697, 120.646);
INSERT INTO `region` (`parent_id`, `name`, `latitude`, `longitude`)
VALUES (@wujiang_id, '平望镇', 31.1791, 120.6411),
(@wujiang_id, '黎里镇', 31.1791, 120.6411);
INSERT INTO `region` (`parent_id`, `name`, `latitude`, `longitude`)
VALUES (@jiangsu_id, '无锡市', 31.5704, 120.3055);
SET @wuxi_id = (SELECT `id` FROM `region` WHERE `name` = '无锡市');
INSERT INTO `region` (`parent_id`, `name`, `latitude`, `longitude`)
VALUES (@wuxi_id, '锡山区', 31.5887, 120.3573),
(@wuxi_id, '惠山区', 31.6514, 120.3036),
(@wuxi_id, '滨湖区', 31.5502, 120.2598),
(@wuxi_id, '江阴市', 31.9086, 120.2855),
(@wuxi_id, '宜兴市', 31.3623, 119.8233);
二、查询所有子节点
从指定的父节点开始,递归查找所有子级地区:
WITH RECURSIVE region_cte AS (
SELECT id, name, parent_id
FROM region
WHERE name = '苏州市' -- 根据指定父节点开始
UNION ALL
SELECT r.id, r.name, r.parent_id
FROM region r
JOIN region_cte c ON r.parent_id = c.id -- 递归查找所有子地区
)
SELECT * FROM region_cte
查询结果:
三、查询所有父节点
从指定的子节点开始,递归查找所有父级地区:
WITH RECURSIVE region_cte AS (
SELECT id, name, parent_id
FROM region
WHERE name = '张家港市' -- 从指定子节点开始
UNION ALL
SELECT r.id, r.name, r.parent_id
FROM region r
JOIN region_cte c ON r.id = c.parent_id -- 递归查找父级区域
)
SELECT * FROM region_cte
查询结果:
四、查询指定节点的根节点
可以通过递归查找父节点,最终筛选出根节点(即没有父节点的):
WITH RECURSIVE region_cte AS (
SELECT id, name, parent_id
FROM region
WHERE name = '张家港市' -- 从指定节点开始
UNION ALL
SELECT r.id, r.name, r.parent_id
FROM region r
JOIN region_cte c ON r.id = c.parent_id -- 递归查找父级区域
)
SELECT * FROM region_cte
WHERE parent_id IS NULL -- 筛选根节点
查询结果:
五、查询所有兄弟节点(同级节点)
查找与指定节点同级的所有区域:
SELECT id, name, parent_id
FROM region
WHERE parent_id = (SELECT parent_id FROM region WHERE name = '张家港市') -- 获取同级父节点
AND name != '张家港市' -- 排除自身
查询结果:
六、获取祖先节点及其所有子节点
获取指定节点的祖先以及每个祖先的所有子节点:
WITH RECURSIVE region_ancestors AS (
SELECT id, name, parent_id
FROM region
WHERE name = '张家港市' -- 从指定节点开始查找祖先
UNION ALL
SELECT r.id, r.name, r.parent_id
FROM region r
JOIN region_ancestors c ON r.id = c.parent_id -- 递归查找所有父级区域
),
region_children AS (
SELECT id, name, parent_id
FROM region
UNION ALL
SELECT r.id, r.name, r.parent_id
FROM region r
JOIN region_children c ON r.parent_id = c.id -- 递归查找所有子级区域
)
SELECT * FROM region_ancestors
UNION
SELECT * FROM region_children
WHERE parent_id IN (SELECT id FROM region_ancestors) -- 获取所有祖先的子节点
查询结果:
七、查询每个节点之间的层级关系
返回每个地区的详细信息,包括其层级和路径:
WITH RECURSIVE region_tree (id, name, parent_id, level, path) AS (
-- 选择根节点,即没有父节点的区域
SELECT
id,
name,
parent_id,
1 AS level,
CAST(name AS CHAR(200)) AS path
FROM region
WHERE parent_id IS NULL
UNION ALL
-- 递归查找子区域
SELECT
r.id,
r.name,
r.parent_id,
rt.level + 1 AS level,
CONCAT(rt.path, ' -> ', r.name) AS path
FROM region r
JOIN region_tree rt ON r.parent_id = rt.id
)
-- 查询结果
SELECT
id, name, parent_id, level, path
FROM region_tree
ORDER BY id -- 根据需要排序
查询结果:
八、查询指定节点之间的层级关系
假设获取苏州市(或其他特定节点)的所有子节点及其层级结构
WITH RECURSIVE region_tree (id, name, parent_id, level, path) AS (
-- 选择指定节点作为根节点
SELECT
id,
name,
parent_id,
1 AS level,
CAST(name AS CHAR(200)) AS path
FROM region
WHERE name = '苏州市' -- 替换为你想要查询的节点名称
UNION ALL
-- 递归查找子区域
SELECT
r.id,
r.name,
r.parent_id,
rt.level + 1 AS level,
CONCAT(rt.path, ' -> ', r.name) AS path
FROM region r
JOIN region_tree rt ON r.parent_id = rt.id
)
-- 查询结果
SELECT
id, name, parent_id, level, path
FROM region_tree
ORDER BY level, id -- 根据层级和 ID 排序
查询结果: