SQL 高级查询(层次化查询,递归)
SQL 高级查询
前面我们写了一下 SQL 的极简入门,今天来说点高级查询。没看到的朋友可以点击下面链接查看。
1 小时 SQL 极速入门(一)
1 小时 SQL 极速入门(二)
1 小时 SQL 极速入门(三)
层次化查询
层次化结构可以理解为树状数据结构,由节点构成。比如常见的组织结构由一个总经理,多个副总经理,多个部门部长组成。再比如在生产制造中一件产品会有多个子零件组成。举个简单的例子,如下图所示

汽车作为根节点,下面包含发动机和车身两个子节点,而子节点又是由其他叶节点构成。(叶节点表示没有子节点的节点)
假如我们要把这些产品信息存储到数据库中,会形成如下数据表。

我们用 parent_product_id 列表示当前产品的父产品是哪一个。
那么用 SQL 语句如何进行层次化查询呢?这里就要用到 CONNECT BY 和 START WITH 语法。
我们先把 SQL 写出来,再来解释其中的含义。
SELECT
level,
id,
parent_product_id,
name
FROM
product
START WITH id = 1
CONNECT BY prior id = parent_product_id
ORDER BY
level
查询结果如下:

解释一下:LEVEL 列表示当前产品属于第几层级。START WITH 表示从哪一个产品开始查询,CONNECT BY PRIOR 表示父节点与子节点的关系,每一个产品的 ID 指向一个父产品。
如果我们把 START WITH 的查询起点改为 id = 2,重新运行上面的 SQL 语句将会得到如下结果:

因为 id=2 的产品是车身,我们就只能查到车身下面的子产品。
当然,我们可以把查询结果美化一下,使其更有层次感,我们让根节点下面的 LEVEL 前面加几个空格即可。把上面的 SQL 稍微修改一下。为每个 LEVEL 前面增加 2*(LEVEL-1)个空格,这样第二层就会增加两个空格,第三层会增加四个空格。
SELECT
level,
id,
parent_product_id,
LPAD(' ', 2 * (level - 1)) || name AS name
FROM
product
START WITH id = 1
CONNECT BY prior id = parent_product_id
查询结果已经有了层次感,如下图:

递归查询
除了使用上面我们说的方法,还可以使用递归查询得到同样的结果。递归会用到 WITH 语句。普通的 WITH 语句可以看作一个子查询,我们在 WITH 外部可以直接使用这个子查询的内容。
当递归查询时,我们是在 WITH 语句内部来引用这个子查询。还是上面的例子,我们使用 WITH 语句来查询。
WITH
temp_product (product_level, id, parent_product_id,name) AS
(
SELECT
0 AS product_level,id,parent_product_id,name
FROM
product
WHERE
parent_product_id IS NULL
UNION ALL
SELECT
tp.product_level + 1,p.id,
p.parent_product_id,
p.name
FROM
product p
JOIN temp_product tp
ON
p.parent_product_id=tp.id
)
SELECT
product_level,
id,
parent_product_id,
LPAD(' ', 2 * product_level)
|| name AS NAME
FROM
temp_product;
第一条 SELECT 语句我们查询出来了根节点,并且设置为 level = 0,第二条SELECT 语句关联上 WITH 语句自身,并且 level 每层加 1 进行递归。
查询结果如下:

可以看到第一列是展示的产品层级,和我们上面查询出来的结果是一致的。
同时使用 WITH 递归时还可以使用深度优先搜索和广度优先搜索,什么意思呢?广度优先就是在返回子行之前首先返回兄弟行,如上图,首先把车身和发动机两个兄弟行返回,之后是他们下面的子行。相反,深度优先就是首先返回一个父节点的子行再返回另一个兄弟行。
我们只需要在 SELECT 语句上方加上下面语句即可实现深度优先搜索查询。
search depth FIRST BY id
SET order_by_id
结果如下,看到首先返回每个父节点下的子行,再返回另一个父节点。

同理,广度优先使用的是下面的 SQL 语句
search breadth FIRST BY id
SET order_by_id
SQL 高级查询(层次化查询,递归)的更多相关文章
- SQL基础-->层次化查询(START BY ... CONNECT BY PRIOR)
--====================================================== --SQL基础-->层次化查询(START BY ... CONNECT BY ...
- oracle 层次化查询(生成菜单树等)
1.简介:Oracle层次化查询是Oracle特有的功能实现,主要用于返回一个数据集,这个数据集存在树的关系(数据集中存在一个Pid记录着当前数据集某一条记录的Id). 2.层次化查询主要包含两个子句 ...
- SQL基础-->层次化查询(START BY ... CONNECT BY PRIOR)[转]
--====================================================== --SQL基础-->层次化查询(START BY ... CONNECT BY ...
- SQL高级查询基础
1.UNION,EXCEPT,INTERSECT运算符 A,UNION 运算符 UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表. ...
- SQL高级查询技巧
SQL高级查询技巧 1.UNION,EXCEPT,INTERSECT运算符 A,UNION 运算符 UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重 ...
- MYSQL SQL高级查询技巧
1.UNION,EXCEPT,INTERSECT运算符 A,UNION 运算符 UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表. ...
- ylb: SQL表的高级查询-子查询
ylbtech-SQL Server: SQL Server- SQL表的高级查询-子查询 SQL Server 表的高级查询-子查询. 1,ylb:表的高级查询-子查询返回顶部 --======== ...
- 【SQL】CONNECT BY 层次化查询
层次化查询,顾名思义就是把查询结果有层次的呈现出来.层次化查询结果类似于树状结构,最顶端的是“根节点”,下面是“父节点”,没有子节点的是“叶节点”. 为了让一个或多个表具有层次关系,必须使用相关的字段 ...
- SQL————高级查询
高级查询 --连接查询 select * from 表1,表2 ————形成笛卡尔积 select * from 表1,表2 where 表1.主键=表2.外键 ————主外键位置可以互换 --jo ...
随机推荐
- java.lang.IllegalArgumentException: Request header is too large
tomcat运行项目时,有一个请求过去后,后台报这样的错java.lang.IllegalArgumentException: Request header is too large原因:请求头超过了 ...
- 配置windbg遇到的问题
这几天在学用windbg分析进程的PTE和PDE内容,不过在配置windbg的过程中就遇到了不少问题.以下是步骤,可供参考. 1. 下载windbg,建议选择32位的.然后去 http://www.m ...
- datetime日期和时间
datetime是Python处理日期和时间的标准库. from datetime import datetime # 获取当前时间 now = datetime.now() print(now) # ...
- 使用wordpress搭建自己的独立博客
最近想要搭建自己的私人博客, 各种百度,完整的搭建步骤如下! 首先得要有自己的vps或者云主机,我这里是自己的云主机,有自己的域名(我这边目前没有买域名)! 搭建步骤! 1,安装lnmp(linux+ ...
- Connection reset by peer的常见原因
1,如果一端的Socket被关闭(或主动关闭,或因为异常退出而 引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer). Socket默认连接60秒 ...
- 电脑开机失败提示"用户配置文件服务登录失败"的三种解决办法
最近遇到这样一个怪现象,就是每次打开电脑输入密码,突然提示"User Profile Service 服务未能登录,无法加载用户配置文件",然后就没办法正常开机了,为什么会这样呢? ...
- 深入解读Service Mesh的数据面Envoy
在前面的一篇文章中,详细解读了Service Mesh中的技术细节,深入解读Service Mesh背后的技术细节. 但是对于数据面的关键组件Envoy没有详细解读,这篇文章补上. 一.Envoy的工 ...
- Bug的严重等级和优先级别与分类
一. Bug的严重等级定义: 1. Blocker 即系统无法执行.崩溃或严重资源不足.应用模块无法启动或异常退出.无法测试.造成系统不稳定. 严重花屏 内存泄漏 用户数据丢失或破坏 系统崩溃/死机/ ...
- 代码转换为html显示
需要将代码转换为 html 使其显示好看一些,可以在这里进行装换: https://tohtml.com/ http://hilite.me/
- 腾讯云存储专家深度解读基于Ceph对象存储的混合云机制
背景 毫无疑问,乘着云计算发展的东风,Ceph已经是当今最火热的软件定义存储开源项目.如下图所示,它在同一底层平台之上可以对外提供三种存储接口,分别是文件存储.对象存储以及块存储,本文主要关注的是对象 ...