当前位置: 首页 > news >正文

【postgresql数据库实现表的树结构查询】

postgresql数据库实现表的树结构查询:

示例数据库表:data_base_basin流域树树结构表

在这里插入图片描述

SQl语句实现树结构

重点函数:WITH RECURSIVE BasinTree AS 。。。
在 PostgreSQL 中,WITH RECURSIVE 是用于实现 递归查询 的功能。它允许你在一个 SQL 查询中反复执行某个子查询,直到满足特定的结束条件。这非常适合处理具有层级结构的数据(如树形结构、图结构)。

什么是 WITH RECURSIVE?
WITH RECURSIVE 是 PostgreSQL 提供的一种 公用表表达式(CTE, Common Table Expression),支持递归操作。

递归 CTE 的基本结构:

WITH RECURSIVE cte_name AS (-- 初始查询(非递归部分)SELECT ...UNION ALL-- 递归查询部分SELECT ...FROM cte_nameWHERE ...
)
SELECT * FROM cte_name;

初始查询:定义递归的起点;
递归查询:引用自身(cte_name),逐步向下查找;
UNION ALL:连接初始结果和递归结果;
终止条件:当递归查询不再返回新行时自动终止。

示例0:表树结构查询:

        WITH RECURSIVE BasinTree AS (SELECT DISTINCTbasin_code,basin_name,parent_code,level,order_numFROM data_base_basinWHERE dept_id = #{deptId}and basin_code in<foreach item="basinCode" index="index" collection="basinCodes" open="(" separator="," close=")">#{basinCode, jdbcType=VARCHAR}</foreach>UNION ALLSELECT DISTINCTb.basin_code,b.basin_name,b.parent_code,b.level,b.order_numFROM data_base_basin bINNER JOIN BasinTree t ON b.basin_code = t.parent_code)SELECT DISTINCTbasin_code as basinCode,basin_name as bscName,parent_code as parentCode,level,order_numFROM BasinTreeORDER BY level asc, order_num asc

示例1:生成数字序列(简单演示)

WITH RECURSIVE numbers AS (SELECT 1 AS nUNION ALLSELECT n + 1 FROM numbers WHERE n < 5
)
SELECT * FROM numbers;

输出:

n
---
1
2
3
4
5

示例 2:查询组织架构中的员工上下级关系(树形结构)

CREATE TABLE employee (id INT PRIMARY KEY,name TEXT,manager_id INT
);

在这里插入图片描述
现在想查出 所有属于 Alice(id=1) 管理链下的员工,包括间接下属。

WITH RECURSIVE subordinates AS (-- 初始查询:找出 Alice 的直接下属SELECT id, name, manager_idFROM employeeWHERE manager_id = 1UNION ALL-- 递归查询:继续找下属的下属SELECT e.id, e.name, e.manager_idFROM employee eINNER JOIN subordinates s ON e.manager_id = s.id
)
-- 最终查询:合并所有结果
SELECT * FROM subordinates;

输出:

id | name   | manager_id
---|--------|-----------
2  | Bob    | 1
3  | Carol  | 2
4  | David  | 2

示例 3:查询路径或层级信息(带深度)

你可以添加一个字段来记录层级深度:

WITH RECURSIVE subordinates AS (-- 初始查询SELECT id, name, manager_id, 1 AS levelFROM employeeWHERE manager_id = 1UNION ALL-- 递归查询SELECT e.id, e.name, e.manager_id, s.level + 1FROM employee eINNER JOIN subordinates s ON e.manager_id = s.id
)
SELECT * FROM subordinates;

输出:

id | name   | manager_id | level
---|--------|------------|-------
2  | Bob    | 1          | 1
3  | Carol  | 2          | 2
4  | David  | 2          | 2

注意事项

必须有终止条件
否则会无限递归,最终触发最大递归限制(默认 100 层)

性能问题
如果递归层级很深或数据量大,可能会导致性能下降

避免循环引用
如果父子关系出现环(比如 A → B → A),会导致无限递归并报错

可以加限制
使用 LIMIT 控制最大层级(例如 WHERE level <= 5)

http://www.lryc.cn/news/588391.html

相关文章:

  • 乳化硅油市场报告:深度解析与未来趋势
  • 信息收集的基本流程
  • 非阻塞写入核心:asyncio.StreamWriter 的流量控制与数据推送之道
  • 电流驱动和电压驱动的区别
  • UV vs Pip:Python 包管理的革命性进化
  • redis实现红锁
  • 迅为八核高算力RK3576开发板摄像头实时推理测试 ppyoloe目标检测
  • Java 大视界 -- 基于 Java 的大数据可视化在城市地下管网管理与风险预警中的应用
  • ThreadLocal结构
  • 在Maven多模块项目中进行跨模块的SpringBoot单元测试
  • 考研408《计算机组成原理》复习笔记,第三章(4)——主存与CPU连接(字、位扩展)
  • 研究人员利用提示注入漏洞绕过Meta的Llama防火墙防护
  • 开源软著源代码生成工具(自制)
  • Java行为型模式---模板方法模式
  • 实现高效、可靠的基于骨骼的人体姿态建模(第二章 基于三维人体姿态回归的语义图卷积网络)
  • 如何将 iPhone 备份到云端:完整指南
  • ubuntu系统在线安装postgres
  • 【一维 前缀和+差分】
  • 【牛客刷题】小红的数字删除
  • 第 2 章 数据类型及其运算
  • 内测分发平台应用的异地容灾和负载均衡处理和实现思路
  • 【深度学习笔记】2 浅层神经网络
  • Dubbo 学习笔记
  • python接口自动化 - 使用requests库发送http请求
  • Datawhale AI夏令营——用户新增预测挑战赛
  • Docker入门指南(超详细)
  • 华为OD 消消乐游戏
  • LLaMA.cpp HTTP 服务参数: --pooling 嵌入模型 池化类型详解
  • 【时时三省】(C语言基础)用数组名作函数参数
  • 75、【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例