最近在做一个连续生成问题的时候,百思不得其解该如何解决,最后在朋友的口中得知可以使用 WITH RECURSIVE 来解决,当我了解了之后,voval貌似发现了新大陆,在下方我给出了我自己的一个案例:
以下是一个示例的演示数据,包含了20条记录,分别代表不同的区域(省、市、区)。同时,我也提供了一个使用
WITH RECURSIVE
的 SQL 查询,可以获取每个区域的 id、名字以及上级区域的 pid。
-- 创建演示数据
create table regions(id varchar(10) , name varchar(255), pid varchar(20));
INSERT INTO regions (id, name, pid) VALUES
(1, '省份1', NULL),
(2, '省份2', NULL),
(3, '市1', 1),
(4, '市2', 1),
(5, '区1', 3),
(6, '区2', 3),
(7, '市3', 2),
(8, '区3', 7),
(9, '市4', 2),
(10, '区4', 9),
(11, '市5', 3),
(12, '区5', 11),
(13, '市6', 4),
(14, '区6', 13),
(15, '市7', 2),
(16, '区7', 15),
(17, '市8', 6),
(18, '区8', 17),
(19, '市9', 8),
(20, '区9', 19);
现在,让我们来看一下如何使用 WITH RECURSIVE
来获取每个区域的 id、名字以及上级区域的 pid:
with recursive cet as( select id, name from test1.regions where regions.pid is null union all select t1.id,concat(t2.name,'-->',t1.name) from test1.regions t1 join cet t2 on t1.pid = t2.id ) select id, name from cet;
总结:with recursive 由两部分组成。第一部分是非递归部分( union all 上方),第二部分是递归部分(union all下方)。递归部分第一次进入的时候使用非递归部分传递过来的参数,也就是第一行的数据值,进而得到第二行数据值,然后根据第二行数据值得到第三行数据值。