postgresql 的递归查询
postgresql 的递归查询功能很强大,可以实现传统 sql 无法实现的事情。那递归查询的执行逻辑是什么呢?在递归查询中,我们一般会用到 union 或者 union all,他们两者之间的区别是什么呢?
递归查询的执行逻辑
递归查询的基本语法如下
WITH RECURSIVE ctename AS (SELECT /* non-recursive branch, cannot reference "ctename" */UNION [ALL]SELECT /* recursive branch referencing "ctename" */
)
SELECT ...
FROM ctename ...
其本身也是一个CTE,可以将复杂的查询逻辑进行分离,让整个查询的逻辑更加清晰。对于递归查询而言,分为两部分:
- 非递归部分。即例子中的 UNION [ALL] 的上半部分
- 递归部分。即例子中的 UNION [ALL] 的下半部分
递归查询的逻辑如下:
- 计算非递归部分,其结果将作为递归查询的数据集,也是初始数据集
- 在第一步计算出来的数据上,执行递归部分,新查询出的数据将作为下次递归执行的数据集。也就是说,每次递归使用的数据集都是上次递归的结果
- 直到没有新的数据产生后,递归结束
- 将每一次递归的数据进行聚合,就拿到了最终的数据集
UNION 和 UNION ALL
- UNION: 会将本次递归查询到的数据进行内部去重,也会和之前递归查询出的数据进行去重
- UNION ALL: 不会对数据进行去重
举个例子
// 创建表
create table document_directories
(id bigserial not null,name text not null,created_at timestamp with time zone default CURRENT_TIMESTAMP not null,updated_at timestamp with time zone default CURRENT_TIMESTAMP not null,parent_id bigint default 0 not null
);// 插入示例数据,有两条数据是一样的
INSERT INTO public.document_directories (id, name, created_at, updated_at, parent_id) VALUES (1, '中国', '2020-03-28 15:55:27.137439', '2020-03-28 15:55:27.137439', 0);
INSERT INTO public.document_directories (id, name, created_at, updated_at, parent_id) VALUES (2, '上海', '2020-03-28 15:55:40.894773', '2020-03-28 15:55:40.894773', 1);
INSERT INTO public.document_directories (id, name, created_at, updated_at, parent_id) VALUES (3, '北京', '2020-03-28 15:55:53.631493', '2020-03-28 15:55:53.631493', 1);
INSERT INTO public.document_directories (id, name, created_at, updated_at, parent_id) VALUES (4, '南京', '2020-03-28 15:56:05.496985', '2020-03-28 15:56:05.496985', 1);
INSERT INTO public.document_directories (id, name, created_at, updated_at, parent_id) VALUES (5, '浦东新区', '2020-03-28 15:56:24.824672', '2020-03-28 15:56:24.824672', 2);
INSERT INTO public.document_directories (id, name, created_at, updated_at, parent_id) VALUES (6, '徐汇区', '2020-03-28 15:56:39.664924', '2020-03-28 15:56:39.664924', 2);
INSERT INTO public.document_directories (id, name, created_at, updated_at, parent_id) VALUES (6, '徐汇区', '2020-03-28 15:56:39.664924', '2020-03-28 15:56:39.664924', 2);
使用 UNION ALL 进行数据查询
with recursive sub_shanghai as (select id, name, parent_idfrom document_directorieswhere id=2union allselect dd.id, dd.name, dd.parent_idfrom document_directories ddjoin sub_shanghai on dd.parent_id=sub_shanghai.id)select * from sub_shanghai;
结果如下

使用 UNION 进行查询
with recursive sub_shanghai as (select id, name, parent_idfrom document_directorieswhere id=2unionselect dd.id, dd.name, dd.parent_idfrom document_directories ddjoin sub_shanghai on dd.parent_id=sub_shanghai.id)select * from sub_shanghai;
得到结果如下

我们修改下原始数据,再看下去重逻辑的区别
update document_directories set parent_id = 2 where id=2;
当我们使用 UNION 进行递归查询时,结果并没有发生变化。但是当我们使用 UNION ALL 进行查询时,会一直执行。这是因为 UNION ALL 不会将数据进行去重,而每次递归查询的时候,总归能查询到 {"id": 5, name:"上海", "parent_id": 2} 这条数据,所以递归就没有终止条件。
从而也验证了,UNION 不但会将本次递归查询的数据进行内部去重,也会和之前的递归结果进行去重。
相关文章:
postgresql 的递归查询
postgresql 的递归查询功能很强大,可以实现传统 sql 无法实现的事情。那递归查询的执行逻辑是什么呢?在递归查询中,我们一般会用到 union 或者 union all,他们两者之间的区别是什么呢? 递归查询的执行逻辑 递归查询的…...
Go语言进阶:函数、指针、错误处理
一、函数 函数是基本的代码块,用于执行一个任务。 Go 语言最少有个 main() 函数。 你可以通过函数来划分不同功能,逻辑上每个函数执行的是指定的任务。 函数声明包括函数名﹑形式参数列表﹑返回值列表(可省略)以及函数体。 fun…...
最强自动化测试框架Playwright(30)-JS句柄
在 Playwright 中,JSHandle 是一个表示浏览器中 JavaScript 对象的类。它提供了与网页中的 JavaScript 对象进行交互和操作的方法。 可以通过调用 Playwright中的 evaluateHandle 或 evaluate 方法来获取 JSHandle from playwright.sync_api import sync_playwrig…...
Ctfshow web入门 命令执行RCE篇 web29-web77 与 web118-web124 详细题解 全
Ctfshow 命令执行 web29 pregmatch是正则匹配函数,匹配是否包含flag,if(!preg_match("/flag/i", $c)),/i忽略大小写 可以利用system来间接执行系统命令 flag采用f*绕过,或者mv fl?g.php 1.txt修改文件名,…...
【C++ STL之map,set,pair详解】
目录 一.map映射1.简介2.包含头文件及其初始化3.基本操作4.用迭代器正反遍历5.添加元素的四种方式6.元素的访问7.对比unordered_map,multimap 二.set集合1.简介2.包含头文件及其初始化3.基本操作4.元素的访问5.set,multiset,unordered_set&am…...
Python LEGB规则解析与应用
引言 推荐阅读 AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI绘画、AI讲话、翻译,GPU点亮AI想象空间 资源分享 「java、python面试题」来自UC网盘app分享,打开手机app,额外获得1T空间 http…...
气象监测站:用科技感知气象变化
气象监测站是利用科学技术感知当地小气候变化情况的气象观测仪器,可用于农业、林业、养殖业、畜牧业、环境保护、工业等多个领域,提高对环境数据的利用率,促进产业效能不断提升。 气象监测站主要由气象传感器、数据传输系统、电源系统、支架…...
Linux debian12解压和压缩.rar文件教程
一、Debian12安装rar命令 sudo apt install rar二、使用rar软件 1.解压文件 命令格式: rar x 文件名.rar实例测试: [rootdoudou tmp]# rar x test.rar2.压缩文件 test是一个文件夹 命令格式: rar a 文件名.rar 文件夹名实例测试&#x…...
探析国际大文件传输的花费与降低开销的小妙招
随着全球化的不断发展,跨国企业日益增多,因此国外大文件传输也日益普遍。在这种背景下,国外大文件传输方式的需求也相应增加。本文旨在深入分析国外大文件传输的成本,并提出有效降低这些成本的方法。 一、国外大文件传输成本分析 …...
Linux中shell脚本——for、while循环及脚本练习
目录 一.for循环 1.1.基本格式 1.2.类C语言格式 二.while循环 2.1.基本格式 2.2.死循环语句 三.跳出循环 3.1.continue跳出循环 3.2.break跳出循环 四.常用循环 4.1.循环打印九九乘法表 4.2.循环ping测试某个网段网络连通性 4.3.while死循环实现猜数字游戏 4.4.数…...
【数字实验室】时钟切换
大部分开发者使用 BUFGCTRL 或 BUFGMUX进行时钟切换,它们在时钟切换上可以提供无毛刺输出。然而,了解所涉及的原理是有好处的。 当然,无论我们在同步逻辑中使用哪种技术,重要的是要确保在进行时钟切换时输出上没有毛刺。任何故障都…...
线性代数的学习和整理7:各种特殊效果矩阵特例(草稿-----未完成)
目录 1 矩阵 1.1 1维的矩阵 1.2 2维的矩阵 1.3 没有3维的矩阵---3维的是3阶张量 2 方阵 3 单位矩阵 3.1 单位矩阵的定义 3.2 单位矩阵的特性 3.3 为什么单位矩阵I是 [1,0;0,1] 而不是[0,1;1,0] 或[1,1;1,1] 3.4 零矩阵 3.4 看下这个矩阵 [0,1;1,0] 3.5 看下这个矩阵…...
springBoot 配置文件 spring.mvc.throw-exception-if-no-handler-found 参数的作用
在Spring Boot应用中,可以通过配置文件来控制当找不到请求处理器(handler)时是否抛出异常。具体的配置参数是spring.mvc.throw-exception-if-no-handler-found。 默认情况下,该参数的值为false,即当找不到请求处理器时…...
linux部署kafka3.5.1(单机)
一、下载jdk17 kafka3.x版本需要jdk11以上版本才能更好的兼容,jdk11、jdk17都是LTS长期维护版本,而且jdk17支持springboot3.x,所以我选择了openjdk17。 下载地址: Archived OpenJDK GA Releaseshttps://jdk.java.net/archive/ 二、上传jdk安装包解压 …...
css 实现svg动态图标效果
效果演示: 实现思路:主要是通过css的stroke相关属性来设置实现的。 html代码: <svgt"1692441666814"class"icon"viewBox"0 0 1024 1024"version"1.1"xmlns"http://www.w3.org/2000/svg"p-id"…...
软件测试项目实战,电商业务功能测试点汇总(全覆盖)
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 支付功能怎么测试…...
LeetCode[274]H指数
难度:Medium 题目: 给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。 根据维基百科上 h 指数的定义:h 代表“高引用次数” ,一名科研人员的 h 指…...
MyBatis-Plus快速开始[MyBatis-Plus系列] - 第482篇
悟纤:师傅,MyBatis-Plus被你介绍的这么神乎其乎,咱们还是来的点实际的吧。 师傅:那真是必须的,学习技术常用的一种方法,就是实践。 悟纤:贱贱更健康。 师傅:这… 师傅:…...
CF1003A Polycarp‘s Pockets 题解
题目传送门 题目意思: 给你 n n n 个数,求出最多相同的数的个数。 这道题目有两种解法。 方法一:桶排 一边输入,一边将第 i i i 个数 a i a_i ai 出现的次数存在一个数组 b b b 的第 a i a_i ai 个位置。输入完后遍历…...
数据库厂商智臾科技加入龙蜥社区,打造多样化的数据底座
近日,浙江智臾科技有限公司(以下简称“智臾科技”)正式签署 CLA 贡献者许可协议,加入龙蜥社区(OpenAnolis)。 智臾科技主创团队从 2012 年开始投入研发 DolphinDB。DolphinDB 作为一款基于高性能时序数据库…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...
spring Security对RBAC及其ABAC的支持使用
RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型,它将权限分配给角色,再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...
Linux-进程间的通信
1、IPC: Inter Process Communication(进程间通信): 由于每个进程在操作系统中有独立的地址空间,它们不能像线程那样直接访问彼此的内存,所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...
