id | type | p_id | p_type |
---|---|---|---|
1 | province | 2 | state |
2 | state | 3 | country |
3 | country | 4 | continent |
最近遇到一个问题,有一张mysql地区表,维护了从国家级到市级的地区信息,表结构如上所示:
现在业务需要根据一个子节点查询出根节点(业务中根节点为type='continent')的信息。
自己以前主要用的oracle数据库,如果是oracle的话,可以直接用connect by来实现,然而现在的业务数据库是mysql,没有connect by,只能自己想办法,网上各种查资料(itpub,csdn,博客园,知乎),都是需要用到存储过程或者函数(在此吐槽一句,mysql没法直接调试存储过程和函数,各种不适应啊),后来终于找到一句sql实现的方法(原文链接):
实现如下:
select T2.*
from
(
select @r AS _id,
(SELECT @r := p_id FROM table WHERE id = _id) AS p_id,
@l := @l + 1 AS lvl
from
(select @r := 1, @l := 0) vars,
table_name h
where @r <> 0
) t1
join table_name t2 ON t1._id = t2.id
where type = 'continent'
order BY t1.lvl desc
这里是限定了查询根节点的信息,如果没有根节点限制,该语句可以无限递归查询(当然业务数据库不可能无限分级),某些特殊的业务场景会用到,所以在此记录以备查询。
附:oracle connect by实现(手头没有oracle环境,仅提供思路):
1、由叶子节点查根节点
select * from table start with id=1 connect by id = prior p_id
2、由父节点查叶子节点
select * from table start with p_id=4 connect by prior id = p_id
网友评论