使用 WITH RECURSIVE 实现递归查询

  • SQL查询中WITH xxx as () 是对一个查询子句做别名,同时数据库会对该子句生成临时表(WITH子句只能被SELECT查询块引用)。

  • WITH RECURSIVE 则是一个递归的查询子句,他会把查询出来的结果再次代入到查询子句中继续查询。

创建表并插入数据

create table city
(id        int4,pid     int4,name   varchar(50)
);INSERT INTO "city" ("id", "pid", "name") VALUES (1000, 0, '广东省');
INSERT INTO "city" ("id", "pid", "name") VALUES (1001, 0, '江苏省');
INSERT INTO "city" ("id", "pid", "name") VALUES (1002, 1000, '广州市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1003, 1000, '深圳市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1004, 1000, '佛山市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1005, 1000, '东莞市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1006, 1000, '珠海市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1007, 1000, '中山市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1008, 1000, '惠州市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1009, 1000, '汕头市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1010, 1000, '江门市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1011, 1000, '湛江市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1012, 1000, '肇庆市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1013, 1000, '梅州市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1014, 1000, '茂名市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1015, 1000, '阳江市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1016, 1000, '清远市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1017, 1000, '韶关市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1018, 1000, '揭阳市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1019, 1000, '汕尾市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1020, 1000, '潮州市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1021, 1000, '河源市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1022, 1000, '云浮市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1023, 1001, '南京市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1024, 1001, '苏州市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1025, 1001, '无锡市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1026, 1001, '南通市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1027, 1001, '常州市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1028, 1001, '徐州市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1029, 1001, '盐城市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1030, 1001, '扬州市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1031, 1001, '泰州市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1032, 1001, '镇江市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1033, 1001, '淮安市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1034, 1001, '连云港市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1035, 1001, '宿迁市');
INSERT INTO "city" ("id", "pid", "name") VALUES (1036, 1002, '荔湾区');
INSERT INTO "city" ("id", "pid", "name") VALUES (1037, 1002, '越秀区');
INSERT INTO "city" ("id", "pid", "name") VALUES (1038, 1002, '海珠区');
INSERT INTO "city" ("id", "pid", "name") VALUES (1039, 1002, '天河区');
INSERT INTO "city" ("id", "pid", "name") VALUES (1040, 1002, '白云区');
INSERT INTO "city" ("id", "pid", "name") VALUES (1041, 1002, '黄埔区');
INSERT INTO "city" ("id", "pid", "name") VALUES (1042, 1002, '番禺区');
INSERT INTO "city" ("id", "pid", "name") VALUES (1043, 1002, '花都区');
INSERT INTO "city" ("id", "pid", "name") VALUES (1044, 1002, '萝岗区');
INSERT INTO "city" ("id", "pid", "name") VALUES (1045, 1002, '南沙区');
INSERT INTO "city" ("id", "pid", "name") VALUES (1046, 1002, '增城区');
INSERT INTO "city" ("id", "pid", "name") VALUES (1047, 1002, '从化区');
INSERT INTO "city" ("id", "pid", "name") VALUES (1048, 1024, '姑苏区');
INSERT INTO "city" ("id", "pid", "name") VALUES (1049, 1024, '虎丘区');
INSERT INTO "city" ("id", "pid", "name") VALUES (1050, 1024, '吴中区');
INSERT INTO "city" ("id", "pid", "name") VALUES (1051, 1024, '相城区');
INSERT INTO "city" ("id", "pid", "name") VALUES (1052, 1024, '吴江区');

WITH RECURSIVE 向下递归查询示例

以广东省为根节点,向下查询城市和市区

with recursive c as (select c1.id as id,c1.pid as pid,c1.name as name,1::integer as ll   from city c1where c1.id = 1000union allselect c1.id as id,c1.pid as pid,c1.name as name,c.ll + 1 as ll    from c,city c1where c1.pid = c.id
)
select c.id,c.pid,c.name,c.ll
from c
order by c.id

递归向下查询结果如下图:

二级联动效果查询

with recursive c as (select c1.id as id,c1.pid as pid,cast(c1.name as varchar(100)) as name,1::integer as ll from city c1where c1.id = 1000union allselect c1.id as id,c1.pid as pid,cast(c.name|| '>' || c1.name as varchar(100)) as name,c.ll + 1 as ll from city c1inner join c on c.id = c1.pidwhere c1.pid = c.id
)
select c.id,c.pid,c.name,c.ll
from c
order by c.id

查询结果如下图:

以越秀区为节点向上递归查询

with recursive c as (select c1.id as id,c1.pid as pid,c1.name as name,1::integer as ll   from city c1where c1.id = 1037union allselect c1.id as id,c1.pid as pid,c1.name as name,c.ll + 1 as ll    from c,city c1where c1.id = c.pid
)
select c.id,c.pid,c.name,c.ll
from c
order by c.id

递归向上查询结果如下图:

PostgreSQL实现递归查询相关推荐

  1. PostgreSQL的递归查询(RECURSIVE)

    PostgreSQL的递归查询(RECURSIVE) 实验环境 操作系统:windows 10 家庭中文版数据库系统: PostgreSQL 9.6.2 说明 遇到树形结构的数据时,oracle可以使 ...

  2. [postgresql]postgresql的递归查询sql实例

    --1.递归获取组织树 --创建表 create table public.org_test_t(id int ,name varchar(300),parentid int); --初始化数据 in ...

  3. PostgreSQL Oracle 兼容性之 - INDEX SKIP SCAN (递归查询变态优化) 非驱动列索引扫描优化...

    标签 PostgreSQL , Oracle , index skip scan , 非驱动列条件 , 递归查询 , 子树 背景 对于输入条件在复合索引中为非驱动列的,如何高效的利用索引扫描? 在Or ...

  4. 数据库选型十八摸 之 PostgreSQL - 致 架构师、开发者

    标签 PostgreSQL , 数据库特性 , 数据库应用场景分析 , 数据库选型 背景 数据库对于一家企业来说,相比其他基础组件占据比较核心的位置. 有很多企业由于最初数据库选型问题,导致一错再错, ...

  5. PostgreSQL 图式搜索(graph search)实践 - 百亿级图谱,毫秒响应

    标签 PostgreSQL , CTE , 递归查询 , cycle , depth , loop , deep , level , 层级 , array , row array , JSON 背景 ...

  6. PostgreSQL WITH(WITH RECURSIVE) 查询表达式

    PostgreSQL9.6中对WITH查询有如下描述 WITH提供了一种方式来书写在一个大型查询中使用的辅助语句.这些语句通常被称为公共表 表达式或CTE,它们可以被看成是定义只在一个查询中存在的临时 ...

  7. 【阿里云技术】PostgreSQL的20+种玩法

    作者 德哥,周正中,阿里云高级技术专家,PostgreSQL 中国社区发起人之一,PostgreSQL 象牙塔发起人之一,DBA+社群联合发起人之一,10余项数据库相关专利,曾就职于斯凯网络,负责数据 ...

  8. PostgreSQL递归查询

    出处:http://www.2cto.com/database/201309/242797.html PostgreSQL递归查询 数据库中的数据存在父子关系(单继承,每一条记录只有一个父亲).  如 ...

  9. PostgreSQL 中的递归查询 与oracle 的比较

    PostgreSQL 中的递归查询,2种方法: 1.用with decursive WITH RECURSIVE d AS (SELECT d1.id,d1.parent_id,d1.caption ...

最新文章

  1. 营销自动化的4大预测分析错误
  2. 《编程导论(Java)#183;1.4.1 范式》
  3. [NOI2018]冒泡排序
  4. 第 11 章 日志管理 - 089 - 初探 ELK
  5. Java 函数引用 替代方案
  6. C++里vector::erase函数
  7. mysql5.6设置日志路径_mysql5.6.12切换binlog二进制日志路径_MySQL
  8. 最高响应比优先算法(HRRF)及例题详解
  9. 如何绘制用例图 - How to Draw Use Case Diagram
  10. 使用BeautifulSoup爬取百度图片
  11. 跑得快,打不死!清华大学开发“小强”机器人,壮汉狂踩也挡不住前进步伐
  12. 手机如何将图片缩小到20k?怎么指定压缩图片大小?
  13. 详解Java编码与解码以及常见的编码表,灵活处理乱码问题
  14. 项目实训--Unity多人游戏开发(八、3D音效融合AudioMixer、统一的音频播放系统)
  15. overleaf 中相关的问题
  16. 自定义拍照时 拍照界面_拍照时图片比例怎么选?比构图还要提前一步的摄影攻略要做好...
  17. Qt加载高德在线地图
  18. StackWalker 堆栈打印
  19. 好的数据库面试题集合
  20. 怎么看曲线有没有斜渐近线_关于曲线的斜渐近线

热门文章

  1. 暴风酷播云二期配置_暴风酷播云N3160版硬件折解及安装Proxmox VE-服务器虚拟化系统教程...
  2. 不容错过的用户标签全面解读。建议收藏!
  3. 宝尚12月25日期权操作策略:以高抛低吸为主
  4. matlab求和待定系数,数列求和的待定系数裂项法
  5. GIS中相交的定义(OGC相交的定义)
  6. 宝德服务器 raid制作,宝德服务器RAID操作手册EX16650用户手册.doc
  7. 国债逆回购和债券型基金基础
  8. 基于android的图书馆图书借阅座位预订app
  9. SVN:idea下切换账号
  10. POJ3612 洛谷P2885 [USACO07Nov] Telephone Wire 架设电话线 dp