为了加强对sql处理树状结构的理解,这里以一个真实的案例进行讲解说明:

背景:部门表是树状结构 需求1: 将每个部门的所有的父级节点水平展示出来 需求2: 为每个部门打标归类,父级任意一级节点中含有1的归类成’aaaa’,父级任意一级节点中含有2的归类成’bbbb’,否则归类成’其它’;

示例:这里提供了部门表伪表供测试

SELECT *

FROM VALUES

('1','ab','0')

,('2','ac','0')

,('11','ad','1')

,('12','ae','1')

,('21','af','2')

,('22','ag','2')

,('111','ah','11')

,('112','ai','11')

,('1111','aj','111')

,('1112','ak','111')

,('2201','al','22')

,('2022','am','22') as(id,name,pid)

;

处理这个问题的思路就是将先将部门表扁平化处理,先计算出每个部门ID气对应的所有的父部门ID,并把他们存放到数组结构中,然后再与分类进行比较 注:这里伪表与自己join了4次,至于实际项目中join几次,需要结合实际数据来看,没有统一值的(join次数过多可能会影响性能,join次数过少可能有些层级比较深的部门并没有完整递归所有的父部门ID)

SELECT id1

,name1

,level

,level_arr

,(

CASE WHEN ARRAY_CONTAINS(level_arr,'1') = true THEN 'aaaaa'

WHEN ARRAY_CONTAINS(level_arr,'2') = true THEN 'bbbb'

ELSE '其它'

END

) type

FROM (

SELECT id1

,name1

,CONCAT_WS(',',id1,id2,id3,id4,id5) level

,SPLIT(CONCAT_WS(',',id1,id2,id3,id4,id5),',') level_arr

FROM (

SELECT t1.id id1

,t1.name name1

,IF(t2.id IS NULL,'',t2.id) id2

,IF(t3.id IS NULL,'',t3.id) id3

,IF(t4.id IS NULL,'',t4.id) id4

,IF(t4.pid IS NULL,'',t4.pid) id5

FROM (

SELECT *

FROM VALUES

('1','ab','0')

,('2','ac','0')

,('11','ad','1')

,('12','ae','1')

,('21','af','2')

,('22','ag','2')

,('111','ah','11')

,('112','ai','11')

,('1111','aj','111')

,('1112','ak','111')

,('2201','al','22')

,('2022','am','22') as(id,name,pid)

) t1

LEFT JOIN (

SELECT *

FROM VALUES

('1','ab','0')

,('2','ac','0')

,('11','ad','1')

,('12','ae','1')

,('21','af','2')

,('22','ag','2')

,('111','ah','11')

,('112','ai','11')

,('1111','aj','111')

,('1112','ak','111')

,('2201','al','22')

,('2022','am','22') as(id,name,pid)

) t2

ON t1.pid = t2.id

LEFT JOIN (

SELECT *

FROM VALUES

('1','ab','0')

,('2','ac','0')

,('11','ad','1')

,('12','ae','1')

,('21','af','2')

,('22','ag','2')

,('111','ah','11')

,('112','ai','11')

,('1111','aj','111')

,('1112','ak','111')

,('2201','al','22')

,('2022','am','22') as(id,name,pid)

) t3

ON t2.pid = t3.id

LEFT JOIN (

SELECT *

FROM VALUES

('1','ab','0')

,('2','ac','0')

,('11','ad','1')

,('12','ae','1')

,('21','af','2')

,('22','ag','2')

,('111','ah','11')

,('112','ai','11')

,('1111','aj','111')

,('1112','ak','111')

,('2201','al','22')

,('2022','am','22') as(id,name,pid)

) t4

ON t3.pid = t4.id

)

)

;

相关链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: