- 浏览: 84390 次
- 性别:
- 来自: 广州
文章分类
最新评论
下面这样写是错的。写出这样的语句的实质就是自己误导自己。
with test_cc as ( select 'A' root,'B' parent_root from dual union select 'B','C' from dual union select 'C','D' from dual union select 'C','E' from dual union select 'E','F' from dual ) select level lv, connect_by_root(root) conn_root, connect_by_root(parent_root) conn_parent_root, --最后一个是A的才是leaf connect_by_isleaf, sys_connect_by_path(parent_root,'>')||'>'||root path from test_cc connect by prior root=parent_root;
下面这样写才是对的。
with test_cc as ( select 'A' root,'B' parent_root from dual union select 'B','C' from dual union select 'C','D' from dual union select 'C','E' from dual union select 'E','F' from dual ) select level lv, connect_by_isleaf, connect_by_root(root)||sys_connect_by_path(parent_root,'>') path from test_cc connect by prior parent_root=root;
这边有一个规则:
1.connect by prior 后面跟的是什么,sys_connect_by_path(的后面就要跟着同样的一个东西。否则路径会错。
2.并且不可以使用:root||sys_connect_by_path(parent_root,'>')来连。
必须用 connect_by_root(root)||sys_connect_by_path(parent_root,'>') 才能得到正确的结果。
3.这里还有个规则务必一定要记住:
root parent_root
B C
A B
B D
如果我们想 A,B 去跟上一行的 B,C 或下一行的 B,D 连接
正确的写法是:connect by prior parent_root= root;【1】
而不是写成: connect by parent_root= prior root;【2】
虽然他们表达的意思是一样的。但是对connect_by_isleaf有着相当大的影响。因为你【2】的写法实际上是你把整棵树倒过来了。
A.如果我们写成 connect by parent_root= prior root;会发现sys_connect_by_path的路径是对的。但是connect_by_isleafe的内容就是错的。它把整棵树倒过来了。根节点变成了叶子节点。【站在自己那里连对方】
B.如果我们写成 connect by prior parent_root = root;会发现sys_connect_by_path 的路径是错的而且还少了很多分支。但是connect_by_isleafe的内容是对的。【站在对方那里连自己】
有一个BOM结构表,如下:
首先我要得到顶级零件到最下级零件的全路径:
select level lv, connect_by_isleaf lf, part_no,component_part,per_assembly, connect_by_root(part_no) rt_part_no, connect_by_root(component_part) rt_component_part, sys_connect_by_path(per_assembly,'>') path_value, connect_by_root(part_no)||sys_connect_by_path(component_part,'>') path_correct, substr(sys_connect_by_path(per_assembly,'*'),2,100) path_exp_value from CY_BOM_COMPONENT --(select * from CY_BOM_COMPONENT where part_no='ABDEF') connect by nocycle prior component_part = part_no order by path_correct;
然后我在这些数据的基础上group by.我只要那些叶子节点的内容求和即可得到单个最下级零件和所有零件的总数,因为我把每个叶子节点的地方放置了一个从根到叶子路径的所有值。
select * from( select level lv, connect_by_isleaf lf, part_no,component_part,per_assembly, connect_by_root(part_no) rt_part_no, connect_by_root(component_part) rt_component_part, sys_connect_by_path(per_assembly,'>') path_value, connect_by_root(part_no)||sys_connect_by_path(component_part,'>') path_correct, substr(sys_connect_by_path(per_assembly,'*'),2,100) path_exp_value from CY_BOM_COMPONENT --(select * from CY_BOM_COMPONENT where part_no='ABDEF') connect by nocycle prior component_part = part_no )where lf=1 order by path_correct;
最后算总的结果是:
create or replace function f_calcExpValue(expr varchar2) return number is r number; begin execute immediate 'select '||expr||' from dual' into r; return r; end f_calcExpValue;
select --wm_concat(lv) lv, --max(lf) lf, rt_part_no, --wm_concat(path_correct) path_correct_group, --wm_concat(path_exp_value) path_exp_group, --replace(wm_concat(path_exp_value),',','+') path_exp_value f_calcExpValue(replace(wm_concat(path_exp_value),',','+')) path_exp_value --select * from( select level lv, connect_by_isleaf lf, part_no,component_part,per_assembly, connect_by_root(part_no) rt_part_no, connect_by_root(component_part) rt_component_part, sys_connect_by_path(per_assembly,'>') path_value, connect_by_root(part_no)||sys_connect_by_path(component_part,'>') path_correct, substr(sys_connect_by_path(per_assembly,'*'),2,100) path_exp_value from CY_BOM_COMPONENT --(select * from CY_BOM_COMPONENT where part_no='ABDEF') connect by nocycle prior component_part = part_no )where lf=1 group by rt_part_no order by rt_part_no;
create or replace function f_calcExpValue(expr varchar2) return number is r number; begin execute immediate 'select '||expr||' from dual' into r; return r; end f_calcExpValue; select wm_concat(lv) lv, max(lf) lf, rt_part_no, wm_concat(path_correct) path_correct_group, --wm_concat(path_exp_value) path_exp_group, --replace(wm_concat(path_exp_value),',','+') path_exp_value f_calcExpValue(replace(wm_concat(path_exp_value),',','+')) path_exp_value, wm_concat(path_exp_value_single) path_exp_value_single_group --select * from( select lv,lf,rt_part_no,path_correct,path_exp_value, component_part||':'||f_calcExpValue(path_exp_value) path_exp_value_single from( select level lv, connect_by_isleaf lf, part_no,component_part,per_assembly, connect_by_root(part_no) rt_part_no, connect_by_root(component_part) rt_component_part, sys_connect_by_path(per_assembly,'>') path_value, connect_by_root(part_no)||sys_connect_by_path(component_part,'>') path_correct, substr(sys_connect_by_path(per_assembly,'*'),2,100) path_exp_value from CY_BOM_COMPONENT --(select * from CY_BOM_COMPONENT where part_no='ABDEF') connect by nocycle prior component_part = part_no )where lf=1 ) group by rt_part_no order by rt_part_no;
select rt_part_no as 顶级零件, wm_concat(path_exp_value_single) 需各最下级零件的个数, f_calcExpValue(replace(wm_concat(path_exp_value),',','+')) as 需最下级零件总个数 from( select lv,lf,rt_part_no,path_correct,path_exp_value, component_part||':'||f_calcExpValue(path_exp_value) path_exp_value_single from( select level lv, connect_by_isleaf lf, part_no,component_part,per_assembly, connect_by_root(part_no) rt_part_no, connect_by_root(component_part) rt_component_part, sys_connect_by_path(per_assembly,'>') path_value, connect_by_root(part_no)||sys_connect_by_path(component_part,'>') path_correct, substr(sys_connect_by_path(per_assembly,'*'),2,100) path_exp_value from CY_BOM_COMPONENT --(select * from CY_BOM_COMPONENT where part_no='ABDEF') connect by nocycle prior component_part = part_no )where lf=1 )group by rt_part_no order by rt_part_no;
发表评论
-
让人无语的INSERT语句报错
2014-03-10 14:03 776但是 这又怎么解释呢?? ... -
oracle表空间使用率统计查询
2014-02-25 18:50 654参考文献 文献1:http://blog.itpub.ne ... -
SQL 错误: ORA-00600: 内部错误代码, 参数: [qcsfbdnp:1], [], [], [], []
2014-02-21 17:30 9925call CREATEZHIBIAOPART2('cy_ ... -
INSTR字符串函数
2014-02-13 17:14 695INSTR (源字符串, 目标字符串, ... -
connect by level<n返回的记录条数
2014-02-13 11:25 632connect by是ORACLE 提供的层查询时用的,遍历树 ...
相关推荐
在MySQL中,面对类似Oracle的`connect_by_isleaf`功能的需求,即查找并修改指定ID的所有子级记录,可以通过自连接、存储过程或者递归函数等方法实现。这里我们主要探讨两种MySQL的实现方式:一种是使用用户定义的...
使用 START WITH 和 CONNECT BY 子句可以实现 SQL 的层次查询,并且可以使用 SYS_CONNECT_BY_PATH 函数和 CONNECT_BY_ROOT、CONNECT_BY_ISLEAF、CONNECT_BY_ISCYCLE 等伪列函数来增强层次查询的能力。
总的来说,Oracle SQL提供了丰富的层次查询和数据清理工具,如SYS_CONNECT_BY_PATH、CONNECT_BY_ISLEAF、CONNECT_BY_ROOT和CONNECT_BY_ISCYCLE等,使得在处理层次结构数据和大量数据清理时更为便捷高效。同时,理解...
查询命令:select CONNECT_BY_ISLEAF, dirindex, fatherindex, RPAD(' ',2*(LEVEL-1)) || dirname from t_tonedirlib start with fatherindex = 0 connect by fatherindex = prior dirindex; 这些知识点总结了 SQL ...
SELECT LEVEL, CONNECT_BY_ISCYCLE, CONNECT_BY_ISLEAF, SYS_CONNECT_BY_PATH(a.ename, '/'), a.* FROM empa WHERE a.empno <> 7369 START WITH a.empno = 7839 CONNECT BY NOCYCLE PRIOR a.empno = a.mgr; ``` ...
这些关键词用于构建树状结构,其中`LEVEL`表示层次,`CONNECT_BY_ISLEAF`标识叶子节点,`SYS_CONNECT_BY_PATH`生成路径,`START WITH`指定起始节点,`CONNECT BY PRIOR`定义层级关系,`CONNECT_BY_ROOT`查找根节点,...
例如,在一个员工表中,如果想要查找所有下属及其下属的下属,可以使用`CONNECT BY PRIOR employee_id = manager_id`这样的表达式来定义上下级关系。 2. **Start With**:用来定义查询的起点,即指定哪一行作为树形...
1. 查询本节点及本节点以下的所有节点: ...SELECT RPAD( ' ', 2*(LEVEL-1), '-' ) || DEPNAME "DEPNAME",CONNECT_BY_ROOT DEPNAME "ROOT",CONNECT_BY_ISLEAF "ISLEAF",LEVEL ,SYS_CONNECT_BY_PATH(DEPNAM
Connect By是Oracle用来进行层次查询的语法结构,其原理可以被理解为深度优先遍历(DFS),即从根节点开始,先遍历左子树,再遍历右子树,以此类推,直到找到所有的叶子节点。当使用Connect By进行查询时,每一行...
- **`CONNECT_BY_ISLEAF`**: 如果当前行是叶子节点则返回1,否则返回0。 - **`SYS_CONNECT_BY_PATH`**: 返回路径字符串,其中包含从根到当前节点的所有节点的值。 **示例代码:** ```sql SELECT empno, mgr, ename,...
`CONNECT_BY_ISLEAF` 表达式返回一个布尔值,表示当前节点是否为叶子节点,即没有子节点。 在处理树查询时,应避免 `NULL` 的 `parent_id` 值,因为这可能导致全表扫描,影响性能。建议使用特定的值(如 0)来表示...
- `CONNECT_BY_ISLEAF`标记叶子节点,值为1表示是叶子节点,0则不是。 3. **rpad函数**: `rpad`函数在Oracle SQL中用于右填充字符串,确保字符串达到指定的长度。例如,在给定的例子中,它将乘积的结果填充到...
- CONNECT_BY_ROOT/CONNECT_BY_ISLEAF:在层次查询中使用,标识根节点或叶子节点。 10. **系统信息函数** - USER:返回当前用户的名称。 - DBMS_METADATA:获取对象的DDL语句,用于脚本生成。 以上只是Oracle内...
`LEFT JOIN` 是一种联接(JOIN)类型,它返回所有左表(在本例中是 `TPL` 表)的记录,即使在右表(同样也是 `TPL` 表)中没有匹配的记录。如果在右表中没有找到匹配,结果将用 `NULL` 填充右边列的值。 接着,`...
例如,通过CONNECT_BY_ROOT和CONNECT_BY_ISLEAF等函数在Oracle数据库中实现递归查询。 6. **数据库备份与还原**:定期备份数据库是防止数据丢失的关键步骤。SQL提供多种备份类型,如完整备份、差异备份和日志备份。...
**CONNECT_BY_ISLEAF:** - 判断当前节点是否为叶子节点。 **CONNECT_BY_ISCYCLE:** - 检测是否存在环路。 **SYS_CONNECT_BY_PATH:** - 生成路径字符串,如:`SELECT SYS_CONNECT_BY_PATH(id, '/') FROM table`....
11. **递归函数**:如LEVEL和CONNECT_BY_ISLEAF用于层次查询,实现数据的递归遍历。 12. **排序函数**:RANK(), DENSE_RANK(), ROW_NUMBER()在查询结果中提供行号。 13. **窗口函数**:如LEAD(), LAG(), RANK()等...
- 示例:`SELECT CONNECT_BY_ROOT id, connect_by_isleaf FROM table START WITH condition CONNECT BY PRIOR id = parent_id;` 以上列举了部分Oracle数据库中常用的函数,它们在日常的数据库管理和数据分析中发挥...
- ISLEAF:标记模块是否为叶子节点(是否有子模块)。 - NODEURLTITLE:超链接的title属性,提供额外的描述信息。 5. 系统模块登录表(TB_ADM_MODULE_LOGIN) - UserId:与用户信息表关联,表示用户可以访问的...