Oracle、postgresql递归语法

测试数据

复制代码
CREATE TABLE employees (
  employee_id INT PRIMARY KEY,
  last_name VARCHAR(100),
  manager_id INT
);

INSERT INTO employees VALUES (1, 'CEO', NULL);
INSERT INTO employees VALUES (2, 'Manager A', 1);
INSERT INTO employees VALUES (3, 'Manager B', 1);
INSERT INTO employees VALUES (4, 'Employee A', 2);
INSERT INTO employees VALUES (5, 'Employee B', 2);
INSERT INTO employees VALUES (6, 'Employee C', 3);

ORACLE

在数据库中,递归查询是一种特殊的查询,它可以用来查询具有层次结构的数据,例如员工和他们的经理之间的关系,或者目录和子目录之间的关系。在Oracle和PostgreSQL中,我们可以使用WITH RECURSIVE语句来执行递归查询。

复制代码
SELECT employee_id, last_name, manager_id 
FROM employees where 
START WITH manager_id IS NULL
CONNECT BY PRIOR employee_id = manager_id;

postgresql

复制代码
WITH RECURSIVE employee_recursive AS (
  SELECT employee_id, last_name, manager_id
  FROM employees
  WHERE manager_id IS NULL
  UNION ALL
  SELECT e.employee_id, e.last_name, e.manager_id
  FROM employees e
  INNER JOIN employee_recursive er ON er.employee_id = e.manager_id
)
SELECT * FROM employee_recursive;

在这个查询中,WITH RECURSIVE子句定义了一个递归查询。这个查询由两部分组成,第一部分是基础查询,它定义了递归查询的起点。第二部分是递归查询,它定义了父记录和子记录之间的关系。两部分通过UNION ALL操作符连接起来。

递归查询是一种强大的工具,它可以用来查询具有层次结构的数据。在Oracle和PostgreSQL中,我们可以使用CONNECT BY语句和WITH RECURSIVE语句来执行递归查询。虽然这两种方法的语法有所不同,但它们的基本思想是相同的:定义一个起点,然后定义一个递归关系来遍历数据。

为了避免在递归过程中发生死循环,可以增加level关键字,对下转层级进行约束

oracle

复制代码
SELECT employee_id, last_name, manager_id,level 
FROM employees where level<=2
START WITH manager_id IS NULL
CONNECT BY PRIOR employee_id = manager_id;

postgresql

复制代码
WITH RECURSIVE employee_recursive AS (
  SELECT employee_id, last_name, manager_id, 1 AS level
  FROM employees
  WHERE manager_id IS NULL
  UNION ALL
  SELECT e.employee_id, e.last_name, e.manager_id, er.level + 1
  FROM employees e
  INNER JOIN employee_recursive er ON er.employee_id = e.manager_id
)
SELECT employee_id, last_name, manager_id, level
FROM employee_recursive where level<=2;

关键字解析

Oracle递归查询中的关键字
  • LEVEL: 在Oracle中,LEVEL是一个伪列,它表示在层次查询中的深度级别。在CONNECT BY查询中,可以使用LEVEL来确定行在层次结构中的级别。例如,可以使用LEVEL来缩进层次结构的输出。

  • PRIOR: PRIOR关键字用于在CONNECT BY子句中定义父记录和子记录之间的关系。PRIOR关键字可以让你引用上一级的行。

  • CONNECT BY: CONNECT BY子句用于定义父记录和子记录之间的关系。

  • START WITH: START WITH子句用于定义递归查询的起点。

PostgreSQL递归查询中的关键字
  • WITH RECURSIVE: WITH RECURSIVE子句用于定义一个递归查询。这个查询由两部分组成,第一部分是基础查询,它定义了递归查询的起点。第二部分是递归查询,它定义了父记录和子记录之间的关系。

  • UNION ALL: UNION ALL操作符用于连接基础查询和递归查询的结果。

在使用这些关键字时,需要注意的是,递归查询可能会导致无限循环,特别是当数据中存在循环引用时。因此,当编写递归查询时,需要确保有一个明确的退出条件。

相关推荐
Mr.朱鹏7 小时前
Linux 服务器 LVM 根分区在线动态扩容
linux·服务器·数据库
摇滚侠7 小时前
《SpringBoot 3:入门与应用实战》第 12 章 JDBC 与事务 数据库初始化机制 阅读笔记 36
数据库·spring boot·笔记
qiuhaipeng17 小时前
Claude code 升级后上下文长度变短问题
java·前端·数据库
云贝贝贝8 小时前
腾讯云 TDSQL(MySQL 版)运维高频 6 坑:代理路由、读写分离、分片键、监控、PITR
运维·mysql·腾讯云
wxwx_bscxy3228 小时前
基于Python新冠疫情可视化分析系统的设计与实现
java·数据库·spring boot·python·微信小程序·sqlite
剑之所向9 小时前
.NET 官方`System.Threading.Channels`
前端·javascript·数据库
词却9 小时前
数据库基础:DQL 数据查询语言
数据库·oracle
昌原的儿子LEO11 小时前
Linux IO多路复用与SQLite数据库核心知识点总结
linux·数据库·oracle
山岚的运维笔记12 小时前
mysql 专业笔记 -- 第 8 章:使用变量
运维·数据库·笔记·后端·学习·mysql·dba
聚美智数12 小时前
网安查询-备案查询-网络安全查询API接口介绍
网络·数据库·web安全