SQL的递归查询子/父节点结构(MySQL)

当数据库中存储了树型结构的数据,例如城市表时,我们要搜索一个城市的所有父级城市或所有的子级城市,首先想到的就是利用SQL的递归查询,来看下面的MySQL例子(下列例子MySQL只适用于8.0版本及以上):

  1. 下载SQL,执行
    表结构和数据SQL文件下载(该文件中中国城市可能不全,数据仅供测试使用)

  2. 向下查询(不包含自己)
    比如我们要查山东省的下级所有城市,拿到山东省这条数据的id:370000

    with recursive tb (id, name, parentid) as
    (
      select id, name, parentid 
    	from city 
    	where parentid = 370000
    	
      union all
    	
      select c.id, c.name, c.parentid
    	from city c 
    	join tb t 
    	on c.parentid = t.id
    )
    select *
    from tb;
    

    查询结果如下
    在这里插入图片描述

  3. 向上查询
    比如我们要查历下区的上级所有城市,拿到历下区这条数据的id:370102

    with recursive tb (id, name, parentid) as
    (
      select id, name, parentid 
    	from city 
    	where id = 370102
    	
      union all
    	
      select c.id, c.name, c.parentid
    	from city c 
    	join tb t 
    	on c.id = t.parentid
    )
    select *
    from tb;
    

    查询结果如下:
    在这里插入图片描述

当然,我们有时候要查的是上下级的对应关系。
比如我要查出历下区与所有上级城市的关系:中国-山东省-济南市-历下区
或者要查出一个城市下的所有城市与上级城市的关系,只需对上面的SQL稍加修改就可以了:

  1. 一个城市下的所有城市与上级城市的关系
    第一个select中查询条件为该城市的id,在第二个delect中进行拼接处理,拼接字符自选
    拿山东省为例,山东省的id为370000

    with recursive tb (id, name, parentid) as
    (
     select id, name, parentid 
       from city 
       where id = 370000
       
     union all
       
     select c.id, concat(t.name, '-', c.name) as name, c.parentid
       from city c 
       join tb t 
       on c.parentid = t.id
    )
    select id, name 
    from tb;
    

    查询结果如下:
    在这里插入图片描述

  2. 某一城市的父级城市关系
    还是拿历下区举例,拿到id370102

    with recursive tb (id, name, parentid) as
    (
      select id, name, parentid 
    	from city 
    	where id = 370102
    	
      union all
    	
      select c.id, concat(c.name, '-', t.name) as name, c.parentid
    	from city c 
    	join tb t 
    	on c.id = t.parentid
    )
    select name 
    from tb where parentid = 0;
    

    查询结果如下:
    在这里插入图片描述

其他数据库如DB2等也可以按照同样的思路进行查询,不过需要注意的是其他数据库的SQL语句在with递归的使用和拼接函数concat的使用上可能有不同,进行替换就好

  • 6
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值