RECURSIVE - 递归查询

实际中往往需要涉及到查询一张表中存在上下级关系的数据。

这样的情景有很多,比如岗位配置表,存在多级部门,部门间存在上下级关系;比如业务字典表,存在多级字典,其中也存在上下级关系。

当层级只有一两层的时候,使用关联查询、子查询或者其它任何方式,都能够比较容易完成查询功能。
例如,当存在一个岗位部门表 POST,其中内容结构如下:

POST_CODEPOST_NAMEPOST_PRE_CODE
president总裁办公室
business业务部president
technical技术部president
logistics后勤部president
humanResource人力资源部president
account财务部president
security安保部president
culture企业文化部president

对这样的结构进行查询,并不困难。如下:

SELECT P.POST_CODE,
       CASE
           WHEN P.POST_PRE_CODE IS NULL THEN P.POST_NAME
           ELSE CONCAT_WS(' - ', (SELECT O.POST_NAME FROM POST O WHERE O.POST_CODE = P.POST_PRE_CODE),
                       P.POST_NAME) END AS POST_NAME
FROM POST P ORDER BY POST_PRE_CODE;

得到的结果:

POST_CODEPOST_NAME
president总裁办公室
business总裁办公室 - 业务部
technical总裁办公室 - 技术部
logistics总裁办公室 - 后勤部
humanResource总裁办公室 - 人力资源部
account总裁办公室 - 财务部
security总裁办公室 - 安保部
culture总裁办公室 - 企业文化部

但当层级越来越多之后,查询会变得麻烦起来。

例如,当“技术部”存在下属岗位如“研发组”、“美工组”、“测试组”、“运维组”……再当“研发组”又存在下属岗位“软件开发”、“硬件开发”、“大数据开发”……
可想而知,通过上述的查询SQL已经无法轻易完成这样的查询需求。

在这种情况下,使用 RECURSIVE ,进行递归查询是非常适合的。
再举个例子,存在地区区域表 AREA ,最高层级是省,最低层级到某个县/区的某个地点,至少存在四级结构。

此时想要获取某指定省份,如“湖南省”,在表中全部下属的地市、区县及地点,并让每个地点都附带上它所有的上级结构,该如何通过SQL完成?
使用 RECURSIVE 进行递归查询,会让事情变得简单。如下:

WITH RECURSIVE city AS
(
    SELECT AREA_CODE,
           AREA_NAME
    FROM AREAS
    WHERE AREA_CODE = 'hunan'
    UNION ALL
    SELECT org.AREA_CODE,
           CONCAT_WS(' - ', city.AREA_NAME, org.AREA_NAME) AREA_NAME
    FROM city
             JOIN AREAS org ON org.AREA_PID = city.AREA_CODE
)
SELECT AREA_CODE,
       AREA_NAME
FROM city;

最终,我们可以得到下面的结构

POST_CODEPOST_NAME
hunan湖南省
changsha湖南省 - 长沙市
yueyang湖南省 - 岳阳市
hengyang湖南省 - 衡阳市
xiangtan湖南省 - 湘潭市
furongqu湖南省 - 长沙市 - 芙蓉区
tianxinqu湖南省 - 长沙市 - 天心区
yueluqu湖南省 - 长沙市 - 岳麓区
kaifuqu湖南省 - 长沙市 - 开福区
yuhuaqu湖南省 - 长沙市 - 雨花区
wangchengqu湖南省 - 长沙市 - 望城区
liuyangshi湖南省 - 长沙市 - 浏阳市
ningxiangshi湖南省 - 长沙市 - 宁乡市
changshaxian湖南省 - 长沙市 - 长沙县
junshanqu湖南省 - 岳阳市 - 君山区
xiangyuxian湖南省 - 长沙市 - 芙蓉区 - 湘域熙岸小区
chengshihuayuan湖南省 - 长沙市 - 岳麓区 - 万科城市花园
fangjushoufu湖南省 - 岳阳市 - 君山区 - 房聚首府小区
junshanyihao湖南省 - 岳阳市 - 君山区 - 君山壹号

成功得到满足需求的查询结果。
WITH语句本身能够将复杂语句拆分为多个简单语句,在进行复杂的查询时尤其适用。
而 RECURSIVE 关键字则是起到了引入自身的作用,从而实现了递归查询。

不过需要注意的是,RECURSIVE 仅在MySQL8.0以上的版本才能使用哦

  • 25
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值