首页 > 其他分享 >从概念到实践,带你掌握层次递归查询

从概念到实践,带你掌握层次递归查询

时间:2023-12-08 16:13:40浏览次数:44  
标签:INSERT 层次 递归 area INTO 查询 VALUES

本文分享自华为云社区《GaussDB数据库SQL系列-层次递归查询》,作者: Gauss松鼠会小助手2。

一、前言

层次递归查询是一种常见的SQL查询方式,特别是在一些层次化的数据存储结构中经常用到。本文主要以GaussDB数据库为实验平台,为大家讲解其使用方法。

二、GuassDB数据库层次递归查询概念

层次化结构可以理解为树状数据结构,由节点构成。举个简单的例子,如下图所示,由子节点向上查询根节点,或者由根节点遍历所有子节点:

递归查询是指查询中需要多次调用自身的查询方式。在递归查询中,查询会反复地递归进入到一个子查询中,直到查询得到满足条件的结果或遍历完整个查询范围。递归查询在数据库领域中有着重要的应用。方便数据处理,简化开发代码。

在GaussDB数据库中,递归查询可以通过使用 “select…start with…connect by…prior…” 和“WITH RECURSIVE”语法来实现。

三、GaussDB数据库层次递归查询实验示例

1、创建实验表

--创建实验表

CREATE TABLE area(

a_code VARCHAR(10)

,a_name VARCHAR(10)

,p_a_code VARCHAR(10)

,a_level INT);
--插入测试数据

INSERT INTO area VALUES('610000','陕西省','0','1');

INSERT INTO area VALUES('610100','西安市','610000','2');

INSERT INTO area VALUES('610101','市辖区','610100','3');

INSERT INTO area VALUES('610102','新城区','610100','3');

INSERT INTO area VALUES('610103','碑林区','610100','3');

INSERT INTO area VALUES('610104','莲湖区','610100','3');

INSERT INTO area VALUES('610111','灞桥区','610100','3');

INSERT INTO area VALUES('610112','未央区','610100','3');

INSERT INTO area VALUES('610113','雁塔区','610100','3');

INSERT INTO area VALUES('610114','阎良区','610100','3');

INSERT INTO area VALUES('610115','临潼区','610100','3');

INSERT INTO area VALUES('610116','长安区','610100','3');

INSERT INTO area VALUES('610122','蓝田县','610100','3');

INSERT INTO area VALUES('610124','周至县','610100','3');

INSERT INTO area VALUES('610125','鄠邑区','610100','3');

INSERT INTO area VALUES('610126','高陵区','610100','3');
--查看初始化结果

SELECT * FROM area;

2、sys_connect_by_path(col, separator)

描述:返回从根节点到当前行的连接路径。

参数:col为在路径中显示的列名,支持类型为CHAR/VARCHAR/NVARCHAR2/TEXT的列,参数separator为路径节点之间的分隔符。

返回值类型:text

示例:

-返回从根节点到当前行的连接路径

SELECT *, sys_connect_by_path(a_name, '-') FROM area start with a_code ='610000' connect by prior a_code = p_a_code;

3、connect_by_root(col)

描述:返回当前行的根节点值。

参数:col为输出列的名称。

返回值类型:即为所指定列col的数据类型。

示例:

--返回当前行的根节点值。

SELECT *, connect_by_root(a_name) FROM area start with a_code ='610000' connect by prior a_code = p_a_code;

4、WITH RECURSIVE

使用WITH RECURSIVE 关键字,:

--使用WITH RECURSIVE

WITH RECURSIVE t_area AS (

SELECT a_level,a_code,p_a_code,a_name, a_name ::varchar(50) AS path FROM area WHERE p_a_code = '0'

UNION ALL

SELECT t2.a_level+1,t1.a_code,t1.p_a_code, t1.a_name,CONCAT(t2.path, ',', t1.a_name) ::varchar(50) AS path FROM area t1 JOIN t_area t2 ON t1.p_a_code=t2.a_code

) SELECT * FROM t_area;

示例说明:这个查询使用了递归表达式来遍历省级行政区域关系。表达式使用了两个 SELECT 语句:第一个 SELECT 语句选取了所有父级代码为0的行政区域信息,并将它们添加到临时表 t_area 中。它们的层级选取初始化的a_level级,并且它们的路径被设置为它们的行政区名a_name。这个 SELECT 语句是递归查询的起点。第二个 SELECT 语句连接了 area表和t_area表。它选取了area表中所有具有父级行政区,并连接到t_area表中已经存在的行政区。对于每个连接的行,它们的层级是父级的层级加1,并且它们的路径是父级的路径加上逗号和它们自己的行政区。查询结果返回t_area表中所有的行政区信息。

(“::varchar(50)” 是创建实验表时的字符长度不够,需要重新定义,二是两个SELECT 语句使用 UNION ALL 连接,需要保持类型长度一致)。

四、递归查询的优缺点

1、优点

递归查询能够简化应用程序代码,方便对数据结构的处理。在一些复杂的查询场景中,递归查询能够更快地得到结果。适用于各种类型的树形结构。

2、缺点

递归查询有时可能会产生很多次递归调用,导致性能下降。算法通常比其他方法更复杂,编写比较困难。不适合处理大型数据集。

五、总结

递归查询是一种非常实用的查询方法,在处理分层数据、树形数据等复杂查询场景中非常广泛。但是,在使用递归查询时需要注意一些问题:

• 必须合理控制递归深度,防止过度递归。

• 最好不要在递归查询中执行复杂的计算和组合操作,避免占用过多资源。

• 避免在递归查询中使用ORDER BY操作,这会大大降低性能。

• 在使用递归查询时,应该谨慎处理好死循环问题。

同样的, 在使用GaussDB等数据库时,只要正确合理的应用递归查询,就可以更好地提高查询效率和应用性能。

点击关注,第一时间了解华为云新鲜技术~

 

标签:INSERT,层次,递归,area,INTO,查询,VALUES
From: https://www.cnblogs.com/huaweiyun/p/17888350.html

相关文章

  • 【SQLServer2019备份恢复】查询本身有问题、未正确设置 "ResultSet" 属性、未正确设置
    在SQLServer2019AlwaysOn节点备份策略失败:备份数据库(完整)(8502-HIS-SQLAG\HISAG)备份数据库所在的位置:本地服务器连接兼容性级别为70(SQLServer7.0版)的数据库将被跳过。数据库:所有用户数据库类型:完整追加现有任务开始:2023-12-08T14:10:07。任务结束:20......
  • 递归时间复杂度---黑马程序员
    1.主定理求时间复杂度  展开求时间复杂度 ......
  • Java第五课_函数重载递归和初识数组
    1.函数重载//关键字:public,static等//保留字:关键字的预备役var,goto//jdk11开始,还有JS里var升级为关键字:var变量名=初始值;//重载/overload:在同一个类中,允许函数重名,但是他们的参数列表必须不同.......
  • Mysql之多表查询
    关于Mysql的多表操作表与表的关系通常来说我们根据业务要求及其业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以我们将表与表的关系分为三类一对一一对多多对多物理外键和逻辑外键物理外键是值使用foreignkey作为外键关联另一张表的字段的连接方法物理外......
  • 函数(2)递归
    一、函数递归什么是递归程序调用自身的编程技巧称为递归(recursion)。递归作为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程......
  • 递归
    @OverridepublicList<CategoryEntity>listWithTree(){//1、查询所有分类List<CategoryEntity>entities=baseMapper.selectList(null);//2、组装成树状的父子结构//查出所有的一级分类List<CategoryEntity>collect=entities.stream().filter(categoryEntity->cate......
  • Lucene 查询原基础
    内容收集于知乎,留作学习记录:https://zhuanlan.zhihu.com/p/35814539?spm=ata.21736010.0.0.2b08736byUyj3I前言Lucene是一个基于Java的全文信息检索工具包,目前主流的搜索系统Elasticsearch和solr都是基于lucene的索引和搜索能力进行。想要理解搜索系统的实现原理,就需要深入lu......
  • 7 种查询策略教你用好 Graph RAG 探索知识图谱
    近来NebulaGraph社区在LLM+Graph和GraphRAG领域进行了深入的探索和分享。在LlamaIndex和LangChain中,NebulaGraph引入了一系列知识图谱和图存储工具,支持编排、图谱与大模型间的交互。之前,NebulaGraph布道师古思为作为这项工作的主要贡献者已向大家详细介绍了如何构......
  • java 自定义查询StringBuffer Sql
    一、背景二、实现@AutowiredprivateEntityManagerentityManager;Queryquery=entityManager.createNativeQuery(sql);query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);List<Map<String,Object>>reportWaterTota=qu......
  • 两种方法求字符串个数(函数递归和指针)
    前言:我先想讲一个关于指针的问题,由于我一开始学习指针的时候很困惑,现在分享给大家。假设我们定义一个指针p,我们首先要区分p、&p与*p的区别(对于初学者应该和我一开始一样迷茫)p:p是一个指针变量的名字,表示此指针变量指向的内存地址,如果用%p输出的话它将是一个16进制位的数。*p:*是解引......