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,可以将复杂的查询逻辑进行分离,让整个查询的逻辑更加清晰。对于递归查询而言,分为两部分:

  1. 非递归部分。即例子中的 UNION [ALL] 的上半部分
  2. 递归部分。即例子中的 UNION [ALL] 的下半部分

递归查询的逻辑如下:

  1. 计算非递归部分,其结果将作为递归查询的数据集,也是初始数据集
  2. 在第一步计算出来的数据上,执行递归部分,新查询出的数据将作为下次递归执行的数据集。也就是说,每次递归使用的数据集都是上次递归的结果
  3. 直到没有新的数据产生后,递归结束
  4. 将每一次递归的数据进行聚合,就拿到了最终的数据集

UNION 和 UNION ALL

  1. UNION: 会将本次递归查询到的数据进行内部去重,也会和之前递归查询出的数据进行去重
  2. 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 不但会将本次递归查询的数据进行内部去重,也会和之前的递归结果进行去重。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/46452.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NFTScan NFT API 在 DID Protocol 开发中的应用

自互联网发展以来,Web2.0 时代产生了网络社会,社会已经不再局限于地理边界,而 Web 3.0 引入了去中心化的理念,强调个体数据隐私和可信互操作性。在这个新的时代中,去中心化身份(Decentralized Identifier 即…

linux中shell脚本——shell数组、正则表达式及文件三剑客之AWK

目录 一.shell数组 1.1.数组分类 1.2.定义数组方法 二.正则表达式 2.1.元字符 2.2.表示次数 2.3.位置锚定 2.4.分组 2.5.扩展正则表达式 三.文本三剑客之AWK 3.1.awk介绍及使用格式 3.2.处理动作 3.3.awk选项 3.4.awk处理模式 2.5.awk常见的内置变量 2.6.if条…

pytorch内存泄漏

问题描述: 内存泄漏积累过多最终会导致内存溢出,当内存占用过大,进程会被killed掉。 解决过程: 在代码的运行阶段输出内存占用量,观察在哪一块存在内存剧烈增加或者显存异常变化的情况。但是在这个过程中要分级确认…

uniapp快递信息

uni-app实现一个简易实用物流信息跟踪模板页面_后端物流跟踪模块_鱼翔涌底的博客-CSDN博客

Pytorch-day08-模型进阶训练技巧-checkpoint

PyTorch 模型进阶训练技巧 自定义损失函数动态调整学习率 典型案例:loss上下震荡 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BndMyRX0-1692613806232)(attachment:image-2.png)] 1、自定义损失函数 1、PyTorch已经提供了很多常用…

基于Jenkins构建生产CICD环境(上篇)

目录 环境概述 Jenkins简介 持续集成 持续集成的效益 持续集成的作用 持续集成的特点 持续交付 持续部署 Maven 介绍 安装配置Jenkins Jenkins配置 1、修改jenkins初始密码 2、安装 Jenkins 必要插件 环境概述 随着软件开发需求及复杂度的不断提高,团队…

conda使用教程

Conda介绍 conda可以理解为一个工具,也是一个可执行命令,其核心功能是包管理和环境管理。包管理与pip的使用方法类似似,环境管理则是允许用户方便滴安装不同版本的python环境并在不同环境之间快速地切换。 conda的设计理念 conda将几乎所有…

前端面试的计算机网络部分(3)每天10个小知识点

目录 系列文章目录前端面试的计算机网络部分(1)每天10个小知识点前端面试的计算机网络部分(2)每天10个小知识点 知识点21. 有哪些网络流量分析工具?如何利用它们来分析前端应用的网络请求?**22. 在进行前端…

怎样通过本地电脑搭建SFTP服务器,并实现公网访问?

本地电脑搭建SFTP服务器,并实现公网访问 文章目录 本地电脑搭建SFTP服务器,并实现公网访问1. 搭建SFTP服务器1.1 下载 freesshd 服务器软件1.3 启动SFTP服务1.4 添加用户1.5 保存所有配置 2. 安装SFTP客户端FileZilla测试2.1 配置一个本地SFTP站点2.2 内…

appium2 安装 和出现问题解决

1.安装环境 A macOS, Linux, or Windows operating systemNode.js version in the SemVer range ^14.17.0 || ^16.13.0 || >=18.0.0NPM version >= 8 (NPM is usually bundled with Node.js, but can be upgraded independently) 1.1只要安装nodejs最新版就好了 1.2安…

提升Python代理程序性能的终极解决方案:缓存、连接池和并发

在开发Python代理程序时,优化性能是至关重要的。本文将为你介绍一套终极解决方案,通过缓存、连接池和并发处理等技术,极大地提升Python代理程序的效率和稳定性。 游戏国内地更换虚拟含ip地址数据库地区 1.缓存技术 缓存是 .0-*-696ES2 0一…

el-table分页后序号连续的两种方法

实现效果&#xff1a; 第一页排序到10&#xff0c;第二页的排序应从11开始 实现方法一&#xff1a; 在el-table的序号列中使用template定义 <el-table><el-table-columnmin-width"10%"label"序号"><template slot-scope"scope"…

使用docker-compose.yml快速搭建开发、部署环境(nginx、tomcat、mysql、jar包、各种程序)以及多容器通信和统一配置

目录 docker-compose语法&#xff08;更多说明可查看下面代码&#xff09;imagehostnamecontainer_namevolumesnetworks yml文件的使用启动停止 开发环境&#xff08;这里以python为例&#xff09;部署环境nginxmysqltomcatjar包打包后的可执行程序 常见问题与解决方案多个容器…

网络协议的定义、组成和重要性?

什么是网络协议&#xff1f; 网络协议是在计算机网络中&#xff0c;用于规定通信实体之间进行数据传输和通信的规则集合。网络协议涵盖了各种通信细节&#xff0c;包括数据包格式、错误处理、数据传输速率等&#xff0c;是用于分组交换数据网络的一种协议&#xff0c;其任务仅…

HarmonyOS 设置全屏NoTitleBar

这篇很有用&#xff1a;玩转HarmonyOS 状态栏&标题栏&导航栏相关操作方法整理 配置页面全屏显示(在config.json中配置)&#xff1a; "metaData": {"customizeData": [{"name": "hwc-theme","value": "androi…

二、SQL,如何实现表的创建和查询

1、新建表格&#xff08;在当前数据库中新建一个表格&#xff09;&#xff1a; &#xff08;1&#xff09;基础语法&#xff1a; create table [表名]( [字段:列标签] [该列数据类型] comment [字段注释], [字段:列标签] [该列数据类型] comment [字段注释], ……&#xff0c…

SaaS ERP系统:中小企业走向成功的“秘密武器”

**ERP系统**开发已成为企业以最小的复杂性高效运营的必要需求。企业资源规划是业务流程管理战略不可或缺的一部分&#xff0c;因此&#xff0c;要想在当今动荡的市场中保持竞争力&#xff0c;拥有合适的ERP解决方案至关重要。 尽管如此&#xff0c;由于显而易见的原因&#xf…

音视频 ffplay播放控制

选项说明q, ESC退出播放f全屏切换p, SPC暂停m静音切换9, 09减少音量&#xff0c;0增加音量a循环切换音频流v循环切换视频流t循环切换字幕流c循环切换节目w循环切换过滤器或显示模式s逐帧播放left/right向后/向前拖动10秒down/up向后/向前拖动1分钟鼠标右键单击拖动与显示宽度对…

sourcemap 代码泄露漏洞

啥是source map Sourcemap 本质上是一个信息文件&#xff0c;里面储存着代码转换前后的对应位置信息。 它记录了转换压缩后的代码所对应的转换前的源代码位置&#xff0c;是源代码和生产代码的映射。 source map漏洞呢&#xff1f; 使用reverse-sourcemap工具&#xff0c;利…

玩转单元测试之gtest

引言 程序开发的时候&#xff0c;往往需要编写一些测试样例来完成功能测试&#xff0c;以保证自己的代码在功能上符合预期&#xff0c;能考虑到一些异常边界问题等等。 gtest快速入门 1.引入gtest # 使用的是1.10版本&#xff0c;其他版本可根据需要选择 git clone -b v1.1…