开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情
这篇文章主要介绍树形表的查询方法,主要提到自连接与递归查询两种方法。关于属性表结构应用举例如下:
举个例子:形象一点就类似于掘金首页那样的分类嘛,掘金首页看成根节点,根节点下面又有前端、后端这些二级节点,二级节点下面又有其他三级节点,就这样一级一级的。
那到底什么是树形表结构?
现在来看这张表:前端开发节点是1-1,它的父节点是1,HTML/CSS是节点1-1-1,父节点是1-1。我们可以理解成根节点1下有1-1、1-2、1-3...这样一些一级节点,而一级节点1-1下面又有1-1-1、1-1-2...这样一些二级节点。类似这样的,就是我们说的树形表结构。
我们想查询像这样的一张表(查询两个级别的节点)的数据,应该怎么做呢?
首先第一种方法就是用表的自连接:
SELECT *
FROM course_category one INNER JOIN course_category two
on one.id = two.parentid;
查询结果:
现在这样看着不太舒服,我们优化一下。
SELECT one.id one_id,
one.name one_name,
one.label one_label,
two.id two_id,
two.name two_name,
two.label two_label
FROM course_category one
INNER JOIN course_category two on one.id = two.parentid
WHERE one.parentid='1'
AND one.is_show='1'
AND two.is_show='1'
ORDER BY one.orderby,two.orderby;
运行结果:
这样就看起来更清晰了。
当然有三级节点我们再加inner join嘛,当然这都是建立在需求固定的情况下,我们知道有几级节点。那如果需求不固定,这种自连接的方法就不太合适了。
那第二种方法就是mysql的递归,这种方式可以更灵活的查询树形结构。先来看它的语法结构(WITH语法):
WITH [RECURSIVE]
cte_name [(col_name [, col_name] ...)] AS (subquery)
[, cte_name [(col_name [, col_name] ...)] AS (subquery)] ...
语法中的RECURSIVE表示递归。举个简单的例子,查询5条记录:
with RECURSIVE t1 AS
(
SELECT 1 as n
UNION ALL
SELECT n + 1 FROM t1 WHERE n < 5
)
SELECT * FROM t1;
t1 相当于一个表名,
select 1相当于这个表的初始值,这里使用UNION ALL将初始值加入到表中。
n<5为递归执行的条件,当n>=5时结束递归调用,代码会输出1,2,3,4,5。
那用这种方法怎么实现我们的树形表递归查询呢?
WITH RECURSIVE t1 as
(
select * from course_category p where id= '1'
union all
select t.* from course_category t inner join t1 on t1.id = t.parentid
)
select * from t1 order by t1.id, t1.orderby;
只要t1表节点下面有下属节点t1.id = t.parentid,就会一直往下查。这种是从根节点向下递归,
查询结果:
向上递归的查询:
with recursive t1 as (
select * from course_category p where id= '1-1-1'
union all
select t.* from course_category t inner join t1 on t1.parentid = t.id
)
select * from t1 order by t1.id, t1.orderby;
从1-1-1节点往上找,找父节点,直到查不到上级节点,结果如下:
文末碎语:
- 本章要讲解的主要内容就到这里结束了🔚有哪些不懂的地方欢迎小伙伴们提问👏👏👏
- 文中有任何不对的地方,欢迎大家指正🙏🙏🙏
- 最后,感觉还不错的小伙伴,希望点个👍支持一下