pg 递归算法_postgresql with recursive 递归实现省市区分类查询

本文介绍了如何使用PostgreSQL的WITH RECURSIVE查询来实现递归,特别是针对层次结构数据,如省市区分类查询。通过示例展示了创建表、插入数据,然后使用递归CTE检索特定ID的所有上级节点,并最终通过string_agg函数组合成完整的路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

递归查询使用CTE

WITH查询的一个重要属性是RECURSIVE,使用RECURSIVE属性可以引用自己的输出,从而实现递归,一般用于层次结构或树状结构的应用场景。

例子如下:

id name  fatherid

1 中国 0

2 湖南省 1

3 广东省 1

4 海南省 1

5 河北省 1

6 河南省 1

7 山东省 1

8 湖北省 1

9 江苏省 1

10 深圳市 3

11 长沙市 2

12 南山区 10

13 衡阳市 2

14 耒阳市 13

15 龙岗区 10

16 福田区 10

17 宝安区 10

...

当给定一个ID时能得到它完整的地名,例如当id=7时,地名是:中国广东省深圳市福田区,当ID=16时,地名是:中国广东省深圳市福田区,这是一个层次数据递归应用场景,可以通过PostgreSQL的WITH查询实现,首先创建表并插入数据,如下:

create table test_area(id int4,name varchar(32),fatherid int4);

insert into test_area values (1,'中国',0);

insert into test_area values (2,'湖南省',1);

insert into test_area values (3,'广东省',1);

insert into test_area values (4,'海南省',1);

insert into test_area values (5,'河北省',1);

insert into test_area values (6,'河南省',1);

insert into test_area val

### PostgreSQL 实现省市区递归查询PostgreSQL 中,可以通过 `WITH RECURSIVE` 语句来实现递归查询。对于省市区的数据结构,通常会有一个表包含字段如 `id`(唯一标识)、`name`(行政区划名称)以及 `parent_id`(上级行政区划的ID)。下面是一个具体的例子展示如何构建这样的查询。 #### 创建测试表格并插入数据 为了演示目的,先创建一个简单的 `sys_area` 表,并向其中添加一些样本数据: ```sql CREATE TABLE sys_area ( id SERIAL PRIMARY KEY, name VARCHAR NOT NULL, parent_id INT REFERENCES sys_area(id), UNIQUE (id) ); INSERT INTO sys_area(name, parent_id) VALUES ('China', NULL); INSERT INTO sys_area(name, parent_id) VALUES ('Shandong Province', 1); INSERT INTO sys_area(name, parent_id) VALUES ('Jinan City', 2); INSERT INTO sys_area(name, parent_id) VALUES ('Lixia District', 3); ``` 这段 SQL 脚本定义了一个具有层次关系的地区信息表,并填充了几条记录用于后续查询[^2]。 #### 使用 WITH RECURSIVE 进行递归查询 接下来是实际执行递归查询的部分。这里的目标是从给定的一个区县级别开始,向上追溯到省级甚至国家级别的所有祖先节点: ```sql WITH RECURSIVE area_tree AS ( SELECT a.id, a.name, a.parent_id, ARRAY[a.id] AS path_ids, 0::INT AS depth_level FROM sys_area a WHERE a.id = 4 -- 假设我们从 Lixia District 开始 UNION ALL SELECT child.id, child.name, child.parent_id, parent.path_ids || child.id, parent.depth_level + 1 FROM sys_area child INNER JOIN area_tree parent ON child.id = parent.parent_id ) SELECT * FROM area_tree; ``` 此查询通过自连接的方式逐步遍历每一层父级区域直到顶级节点为止。最终结果不仅返回了路径上的每一个节点的信息,还包括它们之间的层级关系和完整的路径列表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值