树
树,大家都见过,以这种形式的数据关系,就是树。下面看一张图,了解什么是根节点(树干)、节点或分叉、叶(叶节点)
connect by 级联查询
connect by可以用于级联查询,常用于对具有树状结构的记录查询某一节点的所有子孙节点或所有祖辈节点。
来看一个示例,现假设我们拥有一个菜单表t_menu,其中只有三个字段:id、name和parent_id。它们是具有父子关系的,最顶级的菜单对应的parent_id为0。现假设我们拥有如下记录:
id |
name |
parent_id |
1 |
菜单01 |
0 |
2 |
菜单02 |
0 |
3 |
菜单03 |
0 |
4 |
菜单0101 |
1 |
5 |
菜单0102 |
1 |
6 |
菜单0103 |
1 |
7 |
菜单010101 |
4 |
8 |
菜单010201 |
5 |
9 |
菜单010301 |
6 |
10 |
菜单0201 |
2 |
11 |
菜单0202 |
2 |
12 |
菜单020101 |
10 |
13 |
菜单020102 |
10 |
14 |
菜单020103 |
10 |
15 |
菜单0301 |
3 |
16 |
菜单0302 |
3 |
17 |
菜单030201 |
16 |
18 |
菜单030202 |
16 |
19 |
菜单030203 |
16 |
如果这个时候我们需要查询“菜单01”以及其下所有的子孙菜单应该怎么办呢?如果使用connect by的话这将会非常简单,使用如下SQL语句就可以达到对应的效果。
connect by是需要跟start with一起使用的。connect by后跟的是连接条件,在connect by后接的条件通常都需要使用关键字“prior”,可以简单的把它理解为上一级,所以上述例子中“connect by parent_id=prior id”就表示连接条件为parent_id等于上级的id,查找到下一级记录后又会找parent_id等于下一级记录的id的记录,而prior对应的最顶层的记录就是通过start with来确定的,start with后接对应的筛选条件,表示最顶层的记录是哪些,最顶层的记录可以有多个,比如我想查找“菜单01”下的子孙菜单,但是不包括“菜单01”本身,那么我就可以使用如下的SQL语句进行查找,此时“start with parent_id=1”对应的记录就会有多条。
对应的结果为:
id |
name |
parent_id |
4 |
菜单0101 |
1 |
5 |
菜单0102 |
1 |
6 |
菜单0103 |
1 |
7 |
菜单010101 |
4 |
8 |
菜单010201 |
5 |
9 |
菜单010301 |
6 |
此外,如果我们想查找“菜单010101”对应的祖辈菜单也非常简单,如下SQL就可以实现该功能,即从“菜单010101”的父菜单(对应id为4)开始查找。
对应的结果为:
id |
name |
parent_id |
1 |
菜单01 |
0 |
4 |
菜单0101 |
1 |
level
使用connect by时我们可以使用内置的类似于rownum的一个叫level的伪列,该列表示当前记录相对于start with记录的一个层级,start with记录的level为1。如上面的两条SQL语句,如果加上level的话对应的结果将是这样的。
对应的结果为:
level |
id |
name |
parent_id |
1 |
4 |
菜单0101 |
1 |
1 |
5 |
菜单0102 |
1 |
1 |
6 |
菜单0103 |
1 |
2 |
7 |
菜单010101 |
4 |
2 |
8 |
菜单010201 |
5 |
2 |
9 |
菜单010301 |
6 |
对应的结果为:
level |
id |
name |
parent_id |
2 |
1 |
菜单01 |
0 |
1 |
4 |
菜单0101 |
1 |
有了level后,我们就可以对查询的level做一个限制,比如只查从最顶层开始向下两级的菜单。
&