MySQL中向下查询_MySQL/Oracle与向上查询/向下查询

最近项目涉及到数据库向上查询和向下查询。举例来说,以中国行政区划为例,中国行政区分分为:省-市-区县-乡镇,行政区划和行政区划之间通过parent_id形成上下级关系。

以下是一个典型的标准行政区划表,整个中国的行政区划,是一个完整的树形结构:

43350cda60fae6c2f93683401d73838f.png

我们可以通过任意一条记录的parent_id,查询到它的上级行政区划。

现在就有两个不同的业务需求:

1. 通过不知道层级的areaId,查询到它的所有上级;——向上查询

2. 根据一个不知道层级的areaId,查询它的所有子级。——向下查询

一、向上查询

1.1 MySQL实现

SELECT T2.area_id,T2.area_name

FROM (

SELECT

@r AS _id,

(SELECT @r := parent_id FROM base_area WHERE area_id = _id) AS parent_id,

@l := @l + 1 AS lvl

FROM

(SELECT @r := '130102', @l := "0") vars,

base_area h

WHERE @r <> "100000") T1

LEFT JOIN base_area T2

ON T1._id = T2.area_id

查询结果:

653e3ed7f18d6c464332d86f77bb85b5.png

扩展

根据任意级别的行政区划ID,查询这个行政区划的全路径。比如我传入130102,这是长安区的行政区划ID,我能获得一个:河北省 石家庄市 长安区。

SELECT area_id as areaId,GROUP_CONCAT(area_name order by area_level separator ' ') as areaFullName

FROM (

SELECT

@r AS _id,

(SELECT @r := parent_id FROM base_area WHERE area_id = _id) AS p_id,

@l := @l + 1 AS lvl

FROM

(SELECT @r := '130102', @l := 0) vars,

base_area h

WHERE @r != 100000

) T1

JOIN base_area T2

ON T1._id = T2.area_id

查询结果:

6b9e7946b60c9ea032d488327c43f036.png

1.2 Oracle实现

SELECT DISTINCT

area_id,area_name

FROM

base_area

where area_id != '100000'

START WITH area_id = '130102' connect BY prior parent_id = area_id

查询结果:

c4d0714da8e1b7c0f7b0dd4e47709a15.png

扩展

根据任意级别的行政区划ID,查询这个行政区划的全路径。比如我传入130102,这是长安区的行政区划ID,我能获得一个:河北省 石家庄市 长安区。

select area_id,area_name

from(

select

area_id, replace(wm_concat(area_name) over(order by area_level),',',' ') area_name

from(

select area_id,parent_id,area_name,area_level

from base_area

where area_id != 100000

start with area_id = '130102'

connect by prior parent_id = area_id

)

order by area_id desc

) where rownum = 1;

查询结果:

04fd06ce9626fef9637aa368fc0bf39f.png

二、向下查询

1.1 MySQL实现

SELECT

area_id,area_name

FROM

(

SELECT

@ids AS _ids,

( SELECT @ids := GROUP_CONCAT( area_id ) FROM base_area WHERE FIND_IN_SET( parent_id, @ids ) ) AS cids,

@l := @l + 1 AS LEVEL

FROM

base_area,

( SELECT @ids := '130000', @l := 0 ) b

WHERE @ids IS NOT NULL ) id,

base_area DATA

WHERE

FIND_IN_SET(

DATA.area_id,

ID._ids)

查询结果:

dbce0b036d9b0a7c9947c890da1f94b4.png

1.2 Oracle实现

select

area_id,area_name

from

base_area

start with

parent_id = '130000'

connect by prior

area_id = parent_id

d1f934420464c8193d2760981ae64e42.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值