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 高级查询(层次化查询,递归)的更多相关文章

  1. SQL基础-->层次化查询(START BY ... CONNECT BY PRIOR)

    --====================================================== --SQL基础-->层次化查询(START BY ... CONNECT BY ...

  2. oracle 层次化查询(生成菜单树等)

    1.简介:Oracle层次化查询是Oracle特有的功能实现,主要用于返回一个数据集,这个数据集存在树的关系(数据集中存在一个Pid记录着当前数据集某一条记录的Id). 2.层次化查询主要包含两个子句 ...

  3. SQL基础-->层次化查询(START BY ... CONNECT BY PRIOR)[转]

    --====================================================== --SQL基础-->层次化查询(START BY ... CONNECT BY ...

  4. SQL高级查询基础

    1.UNION,EXCEPT,INTERSECT运算符 A,UNION 运算符 UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表. ...

  5. SQL高级查询技巧

    SQL高级查询技巧   1.UNION,EXCEPT,INTERSECT运算符 A,UNION 运算符 UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重 ...

  6. MYSQL SQL高级查询技巧

    1.UNION,EXCEPT,INTERSECT运算符 A,UNION 运算符 UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表. ...

  7. ylb: SQL表的高级查询-子查询

    ylbtech-SQL Server: SQL Server- SQL表的高级查询-子查询 SQL Server 表的高级查询-子查询. 1,ylb:表的高级查询-子查询返回顶部 --======== ...

  8. 【SQL】CONNECT BY 层次化查询

    层次化查询,顾名思义就是把查询结果有层次的呈现出来.层次化查询结果类似于树状结构,最顶端的是“根节点”,下面是“父节点”,没有子节点的是“叶节点”. 为了让一个或多个表具有层次关系,必须使用相关的字段 ...

  9. SQL————高级查询

    高级查询 --连接查询 select * from 表1,表2 ————形成笛卡尔积 select * from 表1,表2 where 表1.主键=表2.外键  ————主外键位置可以互换 --jo ...

随机推荐

  1. Base64 image

    [前端攻略]:玩转图片Base64编码 什么是 base64 编码? 我不是来讲概念的,直接切入正题,图片的 base64 编码就是可以将一副图片数据编码成一串字符串,使用该字符串代替图像地址. 这样 ...

  2. 第三期分享:一款很好用的api文档生成器

    主要用途:生成API的文档 源码链接:https://github.com/tmcw/docbox 最近刚好在看:Trending in open source,在JS语言中,slate一直在周排行上 ...

  3. SwipeListView 详解 实现微信,QQ等滑动删除效果

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/28508769 今天看别人项目,看到别人使用了SwipeListView,Goog ...

  4. 使用画圆的方法来标注指定Id的实体

    //entId为指定实体的Id void SignEnt(AcDbObjectId entId){ AcDbEntity *pEnt = NULL; AcDbBlockReference *pRef; ...

  5. BZOJ_3132_上帝造题的七分钟_树状数组

    BZOJ_3132_上帝造题的七分钟_树状数组 Description “第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为(a,b), ...

  6. TF.learn学习

    官网地址:https://www.tensorflow.org/versions/r1.1/get_started/tflearn 1.代码例子 实现自定义的Estimator 使用DNNClassi ...

  7. 【转】AB实验设计思路及实验落地

    这篇文章会讨论: 在什么情况下需要做 AB 实验 从产品/交互角度,如何设计一个实验 前端工程师如何打点 如何统计数据,并保证数据准确可信 如何分析实验数据,有哪些数据需要重点关注 附:如何搭建前端实 ...

  8. 二维码神器QRCoder

    好久没有写Blog,都是因为不小心坠入了爱河,时间都给我家那位了,都没时间加班了(嗨呀,不小心撒了一下狗粮),不过,还是希望单身的赶紧找到心仪的另一半,实在找不到,那就加班啊(开个玩笑,别认真). 二 ...

  9. Python函数小节

    定义函数时,默认参数必须指向不变的对象 参数为可变对象时,正常调用的时候,结果没有问题,但是当使用默认参数的时候,结果就会和理想的有差距. In [78]: def add(L=[]): ...: L ...

  10. 解决VS2019中.net core WPF 暂时无法使用 Designer 的临时方法

    目录 解决 VS2019 中.net core WPF 暂时无法使用 Designer 的临时方法 安装 vs 2019 professional/enterprise版本 在vs的设置里,勾选.NE ...