首页 置换 选车 估价 问答 生活 经销商 车管所 汽车资讯 汽车销量 车牌查询 今日油价 天气预报
您的位置: 首页 > 生活 > 生活 > sql递归统计的方法(SQL高级查询层次化查询)
sql递归统计的方法(SQL高级查询层次化查询)
更新时间:2024-07-02 18:41:57
SQL 高级查询

前面我们写了一下 SQL 的极简入门,今天来说点高级查询。没看到的朋友可以点击下面链接查看。

1 小时 SQL 极速入门(一)

1 小时 SQL 极速入门(二)

1 小时 SQL 极速入门(三)——分析函数

层次化查询

层次化结构可以理解为树状数据结构,由节点构成。比如常见的组织结构由一个总经理,多个副总经理,多个部门部长组成。再比如在生产制造中一件产品会有多个子零件组成。举个简单的例子,如下图所示

sql递归统计的方法(SQL高级查询层次化查询)1

汽车作为根节点,下面包含发动机和车身两个子节点,而子节点又是由其他叶节点构成。(叶节点表示没有子节点的节点)

假如我们要把这些产品信息存储到数据库中,会形成如下数据表。

sql递归统计的方法(SQL高级查询层次化查询)2

我们用 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

查询结果如下:

sql递归统计的方法(SQL高级查询层次化查询)3

解释一下:LEVEL 列表示当前产品属于第几层级。START WITH 表示从哪一个产品开始查询,CONNECT BY PRIOR 表示父节点与子节点的关系,每一个产品的 ID 指向一个父产品。

如果我们把 START WITH 的查询起点改为 id = 2,重新运行上面的 SQL 语句将会得到如下结果:

sql递归统计的方法(SQL高级查询层次化查询)4

因为 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

查询结果已经有了层次感,如下图:

sql递归统计的方法(SQL高级查询层次化查询)5

递归查询

除了使用上面我们说的方法,还可以使用递归查询得到同样的结果。递归会用到 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 进行递归。

查询结果如下:

sql递归统计的方法(SQL高级查询层次化查询)6

可以看到第一列是展示的产品层级,和我们上面查询出来的结果是一致的。

同时使用 WITH 递归时还可以使用深度优先搜索和广度优先搜索,什么意思呢?广度优先就是在返回子行之前首先返回兄弟行,如上图,首先把车身和发动机两个兄弟行返回,之后是他们下面的子行。相反,深度优先就是首先返回一个父节点的子行再返回另一个兄弟行。

我们只需要在 SELECT 语句上方加上下面语句即可实现深度优先搜索查询。

search depth FIRST BY id SET order_by_id

结果如下,看到首先返回每个父节点下的子行,再返回另一个父节点。

sql递归统计的方法(SQL高级查询层次化查询)7

同理,广度优先使用的是下面的 SQL 语句

search breadth FIRST BY id SET order_by_id

,
相关推荐RECOMMEND
小米10有红外遥控功能吗(小米0有红外吗)
小米10有红外遥控功能吗?小米10全系手机支持红外遥控具备红外遥控功能的手机,可以代替遥控器,来遥控常用的家电,而且一个手机可以储存很多信息,可以控制所有遥控家电,只要在手机里切换即可,非常的方便,今...
小别离演员表全部演员介绍(小别离演员表简单介绍)
小别离演员表全部演员介绍?《小别离》演员表如下:黄磊饰方圆,海清饰童文洁,朱媛媛饰吴佳妮,韩青饰金志明,汪俊饰张亮忠,陈小纭饰蒂娜,张子枫饰方朵朵,胡先煦饰张小宇,赵今麦饰琴琴,陈数饰陈洁,江语晨饰周...
上汽名爵2022年新车计划(空有皮囊底蕴丢失)
当消费者走进上汽名爵4S店看车时,销售人员往往首先会介绍:上汽名爵有着英伦血统,是英国王室的最爱,有着近百年历史的英国运动汽车品牌。目前来看,这样的话术着实令人感觉可笑。不可否认,名爵最早为英国汽车品...
中国有一千元面值的吗(中国曾经有1000元面值的人民币吗)
中国有一千元面值的吗?第一套人民币1948年12月1日--1953年12月陆续发行共12种面额62种版别,其中1元券2种、5元券4种、10元券4种、20元券7种、50元券7种、100元券10种、200...
60岁老人补钙吃什么好(补钙可以给老人吃这些)
60岁老人补钙吃什么好?老年人骨骼老化,且吸收养分特别是钙的能力减弱,这使老年人非常容易发生骨质疏松症所以需要钙的补充,最好是食补和钙剂相结合,我来为大家讲解一下关于60岁老人补钙吃什么好?跟着小编一...
徒法不足以自行是什么意思(徒法不足以自行的含义是什么)
徒法不足以自行是什么意思?徒法不足以自行是一句汉语名言,读音是túfǎbùzúyǐzìxíng,意思是只有法令不能够使之自己发生效力出自《孟子·离娄上》,我来为大家讲解一下关于徒法不足以自行是什么意思...