`

Oracle中关于树递归的一个sql分析

 
阅读更多

总的:select distinct t.id tenantid,

                t.name,
                ts.scnames,
                ts.scids,
                t.remark
  from PM_TENANT t
 inner join (select tenantid,
                    max(substr(scnames, 2)) scnames,--max取scname中包含的个数最多的;substr去第二个字符后面的字符
                    max(substr(scids, 2)) scids
               from (select tenantid,
                            sys_connect_by_path(scnames, ',') scnames,
                            sys_connect_by_path(scids, ',') scids
                       from (select tenantid,
                                    scnames,
                                    scids,
                                    tenantid || rn rchild,--字符串连接
                                    tenantid || (rn - 1) rfather,rn
                               from (select ts.tenantid,
                                            s.name scnames,
                                            s.id scids,
                                            row_number() over(partition by ts.tenantid order by ts.scid) rn  --行序号:以tenenti为分界,不同则从0开始
                                       from pm_tenant_sc ts
                                       left join pm_servicecomponent s on ts.scid = s.id))
                     start with rfather like '%0'--以父节点最后的字符为0的开始
                     connect by prior rchild = rfather--prior 从父节点向下遍历子节点
                     )
              group by tenantid) ts on t.id = ts.tenantid

 

下面来分析:

1:选出行号,不同tenentid,rn从头算,相同tenantid,rn则递增

 

select ts.tenantid,
             s.name scnames,
             s.id scids,
             row_number() over(partition by ts.tenantid order by ts.scid) rn  --行序号:以tenenti为分界,不同则从0开始
             from pm_tenant_sc ts
             left join pm_servicecomponent s on ts.scid = s.id


 

2:得到右孩子与父亲,如10200--》10201--》10202:10200

---》coach(10201)

---》Billy(10202)

 

select tenantid,
                                    scnames,
                                    scids,
                                    tenantid || rn rchild,--字符串连接(tenantid+rn-->rchild)
                                    tenantid || (rn - 1) rfather,rn--tenantid+rn-1-->rfather
                               from (select ts.tenantid,
                                            s.name scnames,
                                            s.id scids,
                                            row_number() over(partition by ts.tenantid order by ts.scid) rn  --行序号:以tenenti为分界,不同则从0开始
                                       from pm_tenant_sc ts
                                       left join pm_servicecomponent s on ts.scid = s.id)


 

3:形成树,用逗号连接各个scnames,scids

 

select tenantid,
                            sys_connect_by_path(scnames, ',') scnames,
                            sys_connect_by_path(scids, ',') scids
                       from (select tenantid,
                                    scnames,
                                    scids,
                                    tenantid || rn rchild,--字符串连接
                                    tenantid || (rn - 1) rfather,rn
                               from (select ts.tenantid,
                                            s.name scnames,
                                            s.id scids,
                                            row_number() over(partition by ts.tenantid order by ts.scid) rn  --行序号:以tenenti为分界,不同则从0开始
                                       from pm_tenant_sc ts
                                       left join pm_servicecomponent s on ts.scid = s.id))
                     start with rfather like '%0'--以父节点最后的字符为0的开始
                     connect by prior rchild = rfather--prior 从父节点向下遍历子节点



4:去掉前面的逗号,并且取scnames,scids最多的那项(去重复)

 

select tenantid,
                    max(substr(scnames, 2)) scnames,--max取scname中包含的个数最多的;substr去第二个字符后面的字符
                    max(substr(scids, 2)) scids
               from (select tenantid,
                            sys_connect_by_path(scnames, ',') scnames,
                            sys_connect_by_path(scids, ',') scids
                       from (select tenantid,
                                    scnames,
                                    scids,
                                    tenantid || rn rchild,--字符串连接
                                    tenantid || (rn - 1) rfather,rn
                               from (select ts.tenantid,
                                            s.name scnames,
                                            s.id scids,
                                            row_number() over(partition by ts.tenantid order by ts.scid) rn  --行序号:以tenenti为分界,不同则从0开始
                                       from pm_tenant_sc ts
                                       left join pm_servicecomponent s on ts.scid = s.id))
                     start with rfather like '%0'--以父节点最后的字符为0的开始
                     connect by prior rchild = rfather--prior 从父节点向下遍历子节点
                     )
              group by tenantid

 


   

 

 

  • 大小: 76 KB
  • 大小: 53.2 KB
  • 大小: 75.4 KB
  • 大小: 66.2 KB
  • 大小: 64.4 KB
分享到:
评论
1 楼 laoli5290 2012-06-25  
分享一下,呵呵!

相关推荐

    Oracle递归SQL学习

    Oracle数据库中的递归SQL是一种强大的工具,用于处理层次结构数据,如组织结构、分类树或者层级关系等。在本主题中,我们将深入探讨如何利用递归SQL在Oracle中展示一棵树形结构,以及如何根据父ID遍历所有的子ID。 ...

    Oracle递归树形结构查询功能

    例如,它可以将每个节点的路径作为字符串返回,便于理解和分析树结构。 在实际应用中,例如组织结构的展示,我们可以创建一个包含部门信息的表`SYS_DEPT`,其中`dept_id`为主键,`par_dept_id`表示父级部门ID,以此...

    递归查询菜单树,支持mysql,oracle

    在IT行业中,数据库管理和数据操作是...总的来说,递归查询菜单树是数据库操作的一个常见应用场景,它涉及到数据库设计、SQL查询技巧以及前后端的数据交换。理解并掌握这些知识点对于开发高效、可维护的系统至关重要。

    oracle递归、迭代

    假设我们有一个名为`TEST_TREE`的表,该表用来存储一个简单的组织结构: ```sql CREATE TABLE TEST_TREE ( ID NUMBER, PID NUMBER, IND NUMBER, NAME VARCHAR2(32) ); ``` 该表记录了以下数据: | ID | PID |...

    Oracle 递归函数介绍

    在上面的示例代码中,我们创建了一个名为 `T_DEPT_HP` 的表,并插入了一些示例数据。然后,我们可以使用递归函数来查询组织结构的每个节点,例如: ```sql WITH RECURSIVE dept_hp AS ( SELECT user_name, dep_name...

    Oracle中的树状查询(递归查询)

    Oracle数据库系统在处理层次数据或树形结构时,提供了强大的工具——递归查询。递归查询允许我们在数据表中处理嵌套级别的数据,这在权限...无论是权限管理还是业务流程分析,递归查询都是一个强大且不可或缺的工具。

    在db2和oracle中的对树的递归查询语句

    同时,为了防止无限递归,通常会设置一个最大递归深度,比如Oracle的`CONNECT_BY_ISCYCLE`和DB2的`WITH RECURSIVE`中的循环检测。 在实际应用中,了解并熟练掌握这些递归查询技巧对于处理树形结构的数据至关重要。...

    Oracle递归查询

    为了更好地理解Oracle中的递归查询,我们首先需要创建一张表格来存储一个简单的树形结构。下面是一张名为`TEST_TREE`的表,包含以下列: - `ID`: 主键,标识每个节点。 - `PID`: 父节点ID,表示当前节点的上一级...

    sql_函数实现三种父子递归

    在SQL中,递归函数是处理层次结构数据的有效方法,特别是在构建树形结构如菜单树或权限树时。本文将探讨如何使用SQL函数实现三种常见的递归查询:找到所有子节点、查找所有父节点以及面包屑导航数据。我们将通过一个...

    Oracle中如何用一条SQL快速生成10万条测试数据

    ROWNUM是Oracle中的一个伪列,用于返回行的顺序号,从1开始递增。在生成测试数据时,ROWNUM可以帮助我们控制生成记录的数量。CONNECT BY LEVEL则是一种递归查询的方法,可以用来生成连续的行,直到LEVEL的值达到指定...

    ORACLE与SQLSERVER语法差异分析

    - SQL SERVER使用窗口函数`ROW_NUMBER() OVER (ORDER BY 列名 升降序)`来为每一行分配一个唯一的行号,可以根据指定的排序标准生成。 3. **字符串长度**: - ORACLE中,`LENGTH()`函数用于计算字符串的长度,包括...

    ORACLE和SQL Server的语法区别

    - **Oracle:** Oracle的INSERT语句允许插入单行或多行数据,也支持从一个表向另一个表插入数据。 ```sql INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2, ...); ``` - **SQL Server:...

    在ORACLE、MSSQL、MYSQL中树结构表递归查询的实现.pdf

    在数据库系统中实现树结构表递归查询是一种常见的需求,它允许我们查询出具有层级关系的数据。ORACLE、MSSQL(Microsoft SQL Server)、MYSQL是三大主流数据库系统,它们各自提供了不同的方式来实现递归查询。 首先...

    oracle SQL递归的使用详解

    在Oracle数据库中,SQL递归查询是一种非常有用的工具,它允许我们处理层级关系的数据,例如组织结构、树形目录或有上下级关联的数据。本文将详细介绍如何在Oracle中使用SQL递归语句,并通过示例进行说明。 首先,...

    递归查询父子关系记录 oracle

    oracle 如何递归查询父子关系。经常用于构造树结构

    oracle递归查询的例子

    本文将通过一个具体的例子来详细介绍如何在 Oracle 中实现递归查询。 #### 二、基础知识回顾 在深入讨论之前,我们需要先了解几个基础概念: 1. **START WITH 子句**:用于指定递归查询的起始条件。 2. **CONNECT ...

    数据库设计之递归树查询

    `WITH`语句,也称为公用表表达式(Common Table Expression, CTE),是SQL中的一种临时结果集,用于定义一个临时的逻辑表,这个表只在当前查询中有效。`WITH`语句配合递归选项,可以实现递归查询,非常适合处理树形...

    SQL语句 递归

    ### SQL语句递归:Oracle中的递归查询详解 在数据库查询语言中,递归查询是一种非常强大的功能,尤其在处理具有层次结构的数据时尤为重要。本文将深入探讨Oracle数据库中的递归查询,包括其基本语法、工作原理以及...

    深入sql oracle递归查询

    在SQL中,递归查询是一种强大的工具,尤其在处理层级数据或者树形结构时非常有用。Oracle数据库和SQL Server都提供了内置的机制来支持递归查询。本文将深入讲解这两种数据库系统如何执行递归查询,并通过示例进行...

    Oracle和SQL_Server的语法区别

    在将 Oracle 数据库中的数据操作语言(DML)语句和过程化语言(PL/SQL)程序迁移至 SQL Server 时,需要考虑以下几个关键点: 1. **DML 语句的语法验证**: - 对于 SELECT、INSERT、UPDATE 和 DELETE 语句,首先要...

Global site tag (gtag.js) - Google Analytics