首页 > 数据库 >数据库递归查询数据 (相关数据库:pg)

数据库递归查询数据 (相关数据库:pg)

时间:2023-07-21 15:13:28浏览次数:30  
标签:name 递归 示例 数据库 tree 查询 pg id

一、PGsql 数据库递归查询

with recursive ag_tree as (select id, title, type, parent_id
                           from agreements
                           where type = 'test'
                           union all
                           select a.id, a.title, a.type, a.parent_id
                           from agreements a
                                    join ag_tree at on a.parent_id = at.id
                           where a.parent_id is not null)
select *
from ag_tree;

-- 递归查询示例:找出员工 "Alice" 的所有直接或间接下属
WITH RECURSIVE employee_tree AS (
    SELECT id, name, manager_id
    FROM employees
    WHERE name = 'Alice'
    UNION ALL
    SELECT e.id, e.name, e.manager_id
    FROM employees e
    JOIN employee_tree et ON e.manager_id = et.id
)
SELECT id, name
FROM employee_tree;

-- 分析
当进行递归查询时,我们使用 Common Table Expressions (CTE) 来实现。递归查询允许查询在查询过程中引用自身的结果。在 PostgreSQL 中,递归查询的语法包括以下几个部分:

1. **WITH RECURSIVE**:
   在递归查询的开始,我们使用 `WITH RECURSIVE` 关键字来声明一个递归查询。`WITH RECURSIVE` 告诉 PostgreSQL 这是一个递归表达式,允许查询引用自身。

2. **递归表达式**:
   在 `WITH RECURSIVE` 关键字后,我们定义一个递归表达式,给它一个名称(例如,`employee_tree`)。递归表达式中包含两个部分:初始部分(Anchor)和递归部分(Recursive)。

3. **初始部分(Anchor)**:
   初始部分是递归查询的起始点。它是一个普通的 SQL 查询,不涉及递归。它返回初始结果集,作为递归的起点。在递归表达式中,初始部分以 `SELECT` 语句开始。

   示例:`SELECT id, name, manager_id FROM employees WHERE name = 'Alice'`

   在上面的示例中,我们选择了名为 "Alice" 的员工信息,作为递归查询的起始点。

4. **递归部分(Recursive)**:
   递归部分定义了递归查询的逻辑。它引用递归表达式的结果,并根据递归条件连接到原始表或视图,以扩展结果集。

   示例:`SELECT e.id, e.name, e.manager_id FROM employees e JOIN employee_tree et ON e.manager_id = et.id`

   在上面的示例中,我们连接 `employees` 表与递归表达式 `employee_tree`,通过 `JOIN` 来找出直接下属,并将它们添加到结果集中。

5. **UNION ALL**:
   在递归表达式的递归部分中,我们使用 `UNION ALL` 运算符将初始部分(Anchor)和递归部分(Recursive)连接在一起。

   示例:`SELECT id, name, manager_id FROM employees WHERE name = 'Alice' UNION ALL SELECT e.id, e.name, e.manager_id FROM employees e JOIN employee_tree et ON e.manager_id = et.id`

   在上面的示例中,我们使用 `UNION ALL` 将初始部分和递归部分连接起来,形成递归查询。

6. **递归终止条件**:
   在递归查询中,必须有一个递归终止条件,用于结束递归。这通常在初始部分或递归部分的 `WHERE` 子句中设置,以防止无限递归。

   示例:在上面的示例中,我们并未显式设置递归终止条件。在这种情况下,递归查询会继续直到没有匹配的下属为止,自然地终止。

7. **最终 SELECT**:
   最后,我们在 `WITH RECURSIVE` 子句的末尾使用一个普通的 `SELECT` 语句来选择递归表达式的结果。这是将递归表达式结果展示给用户的最终结果集。

   示例:`SELECT id, name FROM employee_tree`

   在上面的示例中,我们选择递归表达式 `employee_tree` 中的 `id` 和 `name` 列作为最终结果。

通过 `WITH RECURSIVE` 和 `UNION ALL` 的组合,递归查询允许我们在查询过程中引用自身的结果,从而实现复杂的层次结构数据检索和处理。
-- 分析结束

⚠️注意需要特别注意递归的终止条件,一定要存在且能够正确找到,也可以设置递归层数,确保递归不会太深 具体可自行探索百度

标签:name,递归,示例,数据库,tree,查询,pg,id
From: https://www.cnblogs.com/herebug/p/17571435.html

相关文章

  • 递归
    递归概念简单的来说,递归就是在函数里面再调用它本身,其目的是把复杂的问题分解成与原问题相似但规模较小的问题来解决,这样大大减少了程序的代码量。递归条件递归是需要一个终止条件的,否则就是一个死循环。比如求\(x^n\),可以转化为\(x^n=x*x^{n-1}\),\(x^{n-1}=x*x^{n-2}\)...而......
  • SQL函数大全及示例汇总及不同数据库之间的区别
    SQL函数大全及示例汇总概述SQL中包含以下七种类型的函数:聚合函数:返回汇总值。转型函数:将一种数据类型转换为另外一种。日期函数:处理日期和时间。数学函数:执行算术运算。字符串函数:对字符串、二进制数据或表达式执行操作。系统函数:从数据库返回在SQLSERVER中的值、对......
  • nacos适配达梦、瀚高、人大金仓数据库及部分源码探究
    一.插件实现1.插件目录结构2.pom依赖<dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-datasource-plugin</artifactId><version>2.2.4</version></d......
  • FPGA配合R820T
    想法:FPGA控制R820T的I2C,将R820T输出的中频做处理。准备:某宝买的RTL-SDR,原理如下:软件无线电通过数字信号处理来实现无线信号的调制解调。在RTL-SDR中通过调谐芯片(R820T、E4000)将无线信号下变频至低中频信号,由RTL2832U中的ADC采样得到数字信号,再进行数字下变频得到基带信号,由......
  • OLAP系列之分析型数据库clickhouse单机版部署(一)
    一、概述官网:https://clickhouse.com/docs/zhClickHouse是Yandex于2016年开源的列式存储数据库(DBMS),主要用于在线分析处理查询(OLAP),能够使用SQL查询实时生成分析数据报告.clickhouse优势:与Hadoop、Spark这些巨无霸组件相比,ClickHouse很轻量级,其特点:1.列式存储数据库,数据......
  • pgrep
    pgrep根据用户给出的信息在当前运行进程中查找并列出符合条件的进程ID(PID)补充说明pgrep命令以名称为依据从运行进程队列中查找进程,并显示查找到的进程id。每一个进程ID以一个十进制数表示,通过一个分割字符串和下一个ID分开,默认的分割字符串是一个新行。对于每个属性选项,用户可......
  • Django基本数据库操作
    Django基本数据库操作@目录Django基本数据库操作......
  • windows mysql快速导入数据库文件
    Windows下快速导入MySQL数据库文件在开发和维护项目时,我们通常需要将数据库中的数据导入到本地进行分析和测试。对于MySQL数据库,我们可以通过一些简单的步骤来快速导入数据库文件。在本文中,我们将介绍在Windows环境下如何实现快速导入数据库文件的方法。步骤一:安装MySQL首先,我们......
  • windows java 递归找到文件夹,并修改名称
    WindowsJava递归找到文件夹并修改名称说明在这篇文章中,我将向你解释如何使用Java编写一个递归算法,用于在Windows操作系统中找到文件夹并修改其名称。我将使用Java在Windows环境中进行文件和目录操作。在这个过程中,你将学习如何使用Java的File类来遍历目录树、找到文件夹、修改......
  • .net core连接多个数据库
    .NETCore连接多个数据库在现代的应用程序开发中,通常需要连接多个数据库来存储和检索数据。在.NETCore中,我们可以使用不同的技术和工具来连接多个数据库,这样我们就可以在一个应用程序中操作多个数据库。使用EntityFrameworkCore连接多个数据库EntityFrameworkCore是一个开......