惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Help Net Security
Help Net Security
G
Google Developers Blog
雷峰网
雷峰网
WordPress大学
WordPress大学
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Engineering at Meta
Engineering at Meta
Security Latest
Security Latest
T
Threat Research - Cisco Blogs
AWS News Blog
AWS News Blog
F
Full Disclosure
C
Cybersecurity and Infrastructure Security Agency CISA
T
The Exploit Database - CXSecurity.com
J
Java Code Geeks
U
Unit 42
C
Cyber Attacks, Cyber Crime and Cyber Security
V
V2EX
C
Cisco Blogs
博客园 - 司徒正美
Project Zero
Project Zero
L
LINUX DO - 热门话题
阮一峰的网络日志
阮一峰的网络日志
Blog — PlanetScale
Blog — PlanetScale
Scott Helme
Scott Helme
A
About on SuperTechFans
Hugging Face - Blog
Hugging Face - Blog
S
Securelist
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
S
Schneier on Security
G
GRAHAM CLULEY
酷 壳 – CoolShell
酷 壳 – CoolShell
Cyberwarzone
Cyberwarzone
MongoDB | Blog
MongoDB | Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 叶小钗
T
Threatpost
Recorded Future
Recorded Future
C
CXSECURITY Database RSS Feed - CXSecurity.com
宝玉的分享
宝玉的分享
N
News and Events Feed by Topic
人人都是产品经理
人人都是产品经理
The Register - Security
The Register - Security
S
Security Archives - TechRepublic
博客园 - Franky
N
News | PayPal Newsroom
Simon Willison's Weblog
Simon Willison's Weblog
S
SegmentFault 最新的问题
W
WeLiveSecurity
A
Arctic Wolf
B
Blog

博客园 - leup

一个硬盘的故事 Orcale 临时表 SQL Server 与Oracle的不同点(从微观上) Oracle中Decode()函数使用技巧 oracle 日期函数介绍 Oracle SQLPLUS命令大全 Oracle 自动生成编号(实现sqlserver自增长字段) Oracle 函数介绍之 分析函数 oracle与sqlserver比较 Nhibernate开发资料收集 OWC winform Sample Demo 创建DataTable,并填充数据,模拟数据库中的表 GridView 使用技巧收集 【转】asp.net2.0学习历程 菜鸟到中级程序员的飞跃---30本好书点评 【转】ASP.NET2.0轻松搞定统计图表 【转】ASP.NET2.0 文件图片处理1 ASP.NET2.0 遍历文件夹下所有图片 ASP.NET2.0 ReportingServices 整理1 【转】C#优化字符串操作
Oracle 表内部字段产生树状结构的处理
leup · 2007-11-18 · via 博客园 - leup

connect by prior start with 经常会被用到一个表中存在递归关系的时候。比如我们经常会将一个比较复杂的目录树存储到一个表中。或者将一些部门存储到一个表中,而这些部门互相有隶属关系。这个时候你就会用到connect by prior start with。

典型的使用方法就是:
select * from table connect by prior cur_id=parent_id start with cur_id=???
例如:
a         b
1        0
2        1
3        1
4        2
5        3

如果想查找a=2及其下面的所有数据,则:
select * from table connect by prior a=b start with a=2
a        b
2        1
4        2

首先简单的介绍下connect by语句的使用方法,connect by语句是层次查询中最普遍使用的一种方法,他可以很方便的查询出在有父子关系的表中的所有数据,不多少还是举个例子:

select * from fm_admindept
start with pk=20060517100000
connect by prior pk=parentadmindeptpk
and deleted='0' order by parentadmindeptpk desc

需要注意这里的start with以哪一级开始,以及connect by时的父子关系。

Oracle--树的使用(Connect By)示例

        表    tree
  字段   master
       sub
       sales
  insert into tree values
  ('主1',   '主2',  15); 
  insert into tree values   
  ('主1',   '主3',  20);     
  insert into tree values
  ('主2',   '主4',  5);          
  insert into tree values
  ('主2',   '主5',  10);
  insert into tree values
  ('主3',   '主5',  30);
  insert into tree values
  ('主3',   '主6',  40);
  
  SQL> select * from tree;
  MASTER   SUB       SALES
  ---------- ---------- ----------
  主1    主2        15
  主1    主3        20
  主2    主4         5
  主2    主5        10
  主3    主5        30
  主3    主6        40 
  
  如果用树型结构表示如下:
   '主1'          
     -'主2'       
       --'主4'
       --'主5'
   '主1'          
     -'主3'       
       --'主5'
       --'主6'
  
  SQL> select * from tree                
  start with sub='主2'     --相当于普通sql的where条件
  connect by prior master=sub; --遍历的顺序是sub先于master遍历,也就是说从sub往上遍历一直到master(根节点)
   2 
  MASTER   SUB       SALES
  ---------- ---------- ----------
  主1    主2        15
  
  
  SQL> select * from tree                
  start with master='主2'
  connect by prior master=sub; --sub往上遍历至根节点(参考一下树型图)              
   2  3 
  MASTER   SUB       SALES      
  ---------- ---------- ----------      
  主2    主4         5  --这条是自己本身,也就是第一遍遍历
  主1    主2        15  --这是第2次遍历,我们从树型图可以看到,'主2'往上遍历是'主1'     
  主2    主5        10      
  主1    主2        15      
                        
                         
                        
  好,我们关看上面可能还是不好理解,我们加入一个树结构专用函数sys_connect_by_path,便于理解
  
  SQL> select sys_connect_by_path(MASTER,'/') from tree  --master表示我遍历的起点只找在master列中存在的,如下例只要'主2'为起点,并以/为分割符
  start with master='主2'
  connect by prior master=sub;  --往根节点遍历
   2  3 
  SYS_CONNECT_BY_PATH(MASTER,'/')
  --------------------------------------------------------------------------------
  /主2             --第1遍遍历
  /主2/主1          --第2遍遍历
  /主2             --第2条master='主2'的记录的第1次遍历
  /主2/主1          --第2条master='主2'的记录的第2次遍历
  
  SQL> select sys_connect_by_path(MASTER,'/') from tree --起点为sub='主5'时MASTER=主2,主3
  start with sub='主5'
  connect by prior master=sub;
   2  3 
  SYS_CONNECT_BY_PATH(MASTER,'/')
  --------------------------------------------------------------------------------
  /主2
  /主2/主1
  /主3
  /主3/主1
  
  SQL> select sys_connect_by_path(MASTER,'/'),sub,master from tree  
  start with sub is not null
  connect by prior master=sub; 
   2  3 
  SYS_CONNECT_BY_PATH(MASTER,'/' SUB    MASTER
  ------------------------------ ---------- ----------
  /主1              主2    主1 --找主1到根的路径,这里根是主1他自己
  /主1              主3    主1 
  /主2              主4    主2 
  /主2/主1           主2    主1 --找主2到根的路径,这里根是主1
  /主2              主5    主2
  /主2/主1           主2    主1 
  /主3              主5    主3 
  /主3/主1           主3    主1
  /主3              主6    主3
  /主3/主1           主3    主1  
  select sys_connect_by_path(MASTER,'/'),sub,master from tree                
  start with sub is not null
  connect by prior sub = master;                       
  
  SYS_CONNECT_BY_PATH(MASTER,'/' SUB    MASTER
  ------------------------------ ---------- ----------
  /主1              主2    主1
  /主1/主2           主4    主2
  /主1/主2           主5    主2
  /主1              主3    主1
  /主1/主3           主5    主3
  /主1/主3           主6    主3
  /主2              主4    主2
  /主2              主5    主2
  /主3              主5    主3
  /主3              主6    主3