相关文章推荐
打酱油的椰子  ·  3ds ...·  10 月前    · 
逆袭的签字笔  ·  什么无颜之月画风_哔哩哔哩_bilibili·  1 年前    · 
知识渊博的热带鱼  ·  当硬派SUV加上电机会是怎么样的?试驾坦克5 ...·  1 年前    · 
精明的数据线  ·  echo回声app下载-echo回声 ...·  2 年前    · 
逼格高的打火机  ·  翅膀(电影《再见吧!少年》推广曲)_百度百科·  2 年前    · 
Code  ›  SQL 高级查询 ——(层次化查询,递归)开发者社区
软件 递归 sql语言 产品层次
https://cloud.tencent.com/developer/article/1559389
满身肌肉的包子
1 年前
Lenis

SQL 高级查询 ——(层次化查询,递归)

前往小程序,Get 更优 阅读体验!
立即前往
腾讯云
开发者社区
文档 建议反馈 控制台
首页
学习
活动
专区
工具
TVP
最新优惠活动
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
Lenis
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
社区首页 > 专栏 > SQL 高级查询 ——(层次化查询,递归)

SQL 高级查询 ——(层次化查询,递归)

作者头像
Lenis
发布 于 2019-12-25 15:44:05
3.3K 0
发布 于 2019-12-25 15:44:05
举报
文章被收录于专栏: 有关SQL 有关SQL

阅读文本大概需要 4 分钟。

今天来说点高级查询。

层次化查询

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

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

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

我们用 parent_product_id 列表示当前产品的父产品是哪一个。

那么用 SQL 语句如何进行层次化查询呢?这里就要用到 CONNECT BY 和 START WITH 语法。

我们先把 SQL 写出来,再来解释其中的含义。

代码语言: javascript
复制
SELECT
  level,
  parent_product_id,
  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)个空格,这样第二层就会增加两个空格,第三层会增加四个空格。

代码语言: javascript
复制
SELECT
  level,
  parent_product_id,
  LPAD(' ', 2 * (level - 1)) || name AS name
  product
  START WITH id  = 1
  CONNECT BY prior id = parent_product_id

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

递归查询

除了使用上面我们说的方法,还可以使用递归查询得到同样的结果。递归会用到 WITH 语句。普通的 WITH 语句可以看作一个子查询,我们在 WITH 外部可以直接使用这个子查询的内容。

当递归查询时,我们是在 WITH 语句内部来引用这个子查询。还是上面的例子,我们使用 WITH 语句来查询。

代码语言: javascript
复制
WITH
  temp_product (product_level, id, parent_product_id,name) AS
    SELECT
      0 AS product_level,id,parent_product_id,name
      product
    WHERE
      parent_product_id IS NULL
    UNION ALL
    SELECT
      tp.product_level + 1,p.id,
      p.parent_product_id,
      p.name
      product p
    JOIN temp_product tp
      p.parent_product_id=tp.id
SELECT
  product_level,
  parent_product_id,
  LPAD(' ', 2 * product_level)
  || name AS NAME
 
推荐文章
打酱油的椰子  ·  3ds 火焰纹章if汉化版下载-火焰纹章if白夜/暗夜/透魔汉化中文版下载-k73游戏之家
10 月前
逆袭的签字笔  ·  什么无颜之月画风_哔哩哔哩_bilibili
1 年前
知识渊博的热带鱼  ·  当硬派SUV加上电机会是怎么样的?试驾坦克500 Hi4-T - 知乎
1 年前
精明的数据线  ·  echo回声app下载-echo回声 安卓版v6.8.3-pc6手机下载
2 年前
逼格高的打火机  ·  翅膀(电影《再见吧!少年》推广曲)_百度百科
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号