start with connect by
oracle 提供了start with connect by 语法结构可以实现递归查询。
1. 一个简单举例:
SQL> select * from test;
BILL_MONTH DAY_NUMBER MSISDN
-------------------- ---------- --------------------
200803 1 13800
200803 3 13800
200803 2 13800
200803 2 13801
200803 4 13804
200803 5 13804
200803 7 13804
200803 8 13804
200803 6 13802
200803 6 13801
200803 7 13801
200803 8 13801
12 rows selected
SQL>
SQL> select * from test
2 start with day_number=1
3 connect by prior day_number=day_number+1 and prior msisdn= msisdn
4 ;
BILL_MONTH DAY_NUMBER MSISDN
-------------------- ---------- --------------------
200803 1 13800
200803 2 13800
200803 3 13800
SQL>
上面的语句查找出了从1开始,并且day_number 逐渐+1 递增的,并且 msisdn 相同的哪些个数据.
2. start with connect by 语法结构
如上面说看到的 例子, 其语法结构为 start with condition connect by condition (含 prior 关键字)
start with conditon 给出的seed 数据的范围, connect by 后面给出了递归查询的条件,prior 关键字表示父数据,prior 条件表示子数据需要满足父数据的什么条件。
在下面的这个start with connect by 结构中,就表示 查找出了从1开始,并且day_number 逐渐+1 递增的,并且 msisdn 相同的那些个数据.
start with day_number=1
connect by prior day_number=day_number+1 and prior msisdn= msisdn
3. 执行计划
对于这个特殊的语法结构,我们来看看它的执行计划。
通过下面的执行计划,我们可以看出,对于简单的访问一个对象的递归查询,实际上oracle 要三次访问要查询的对象。因此,这一个告诉我们,在使用递归查询时,一定要谨慎,因为即使原表数据不多,但是三倍的访问喜爱来,代价也会很大。
SQL>set timing on --显示执行时间
SQL>set autotrace on �C显示执行计划
SQL>set autotrace traceonly �C只显示执行计划即不显示查询出来的数据
SQL> explain plan for
2
2 select * from test
3 --where bill_month='200803'
4 start with day_number=1
5 connect by prior day_number=day_number+1 and prior msisdn= msisdn
6 ;
Explained
SQL> select * from table( dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
-------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
-------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | |
|* 1 | CONNECT BY WITH FILTERING| | | | |
|* 2 | FILTER | | | | |
| 3 | TABLE ACCESS FULL | TEST | | | |
| 4 | NESTED LOOPS | | | | |
| 5 | BUFFER SORT | | | | |
| 6 | CONNECT BY PUMP | | | | |
|* 7 | TABLE ACCESS FULL | TEST | | | |
| 8 | TABLE ACCESS FULL | TEST | | | |
-------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("TEST"."DAY_NUMBER"=1)
2 - filter("TEST"."DAY_NUMBER"=1)
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
7 - filter("TEST"."MSISDN"=NULL AND "TEST"."DAY_NUMBER"+1=NULL)
Note: rule based optimization
23 rows selected
SQL>
另外,发现了在含有其他条件的递归中,是先处理所有的递归查询,最后才用加入的条件过滤.
请看下面的例子。
和上面的执行计划对比下我们可以知道,加入条件 where bill_month='200803' 后,实际上却是在递归完成后,最后才执行的 1 - filter("TEST"."BILL_MONTH"='200803') 。
所以,为了确保语句的性能,不要直接加入条件在start with connect by 结构中,而是要想办法将原表的数据控制住。这个可以采用子查询的办法,或者使用临时表等(最好采用临时表,将数据量从本源上控制住;因为从子查询的执行计划我们可以看到,它每次也都是访问全表,再用条件过滤,要重复三次,不是一次过滤就够了).
两种临时表的语法:
create global temporary table 临时表名 on commit preserve|delete rows 用preserve时就是SESSION级的临时表,用delete就是TRANSACTION级的临时表
报表命令
ttitle、btitle、break、compute、spool
分享到:
相关推荐
### Oracle 获取执行计划全部方法详解 #### 方法一:Explain Plan for 方式 - **应用场景**:当某个 SQL 查询执行时间过长甚至无法返回结果时,这种方法尤其适用。 - **步骤**: 1. 使用 `EXPLAIN PLAN FOR` 命令...
DB2虽然没有直接提供类似Oracle的`CONNECT_BY`功能,但可以通过自连接和临时表的方式来实现递归查询。一个典型的例子是使用`WITH RECURSIVE`子句: ```sql WITH RECURSIVE employee_tree (level, employee_id, ...
`WITH`语句,也称为公用表表达式(Common Table Expression, CTE),是SQL中的一种临时结果集,用于定义一个临时的逻辑表,这个表只在当前查询中有效。`WITH`语句配合递归选项,可以实现递归查询,非常适合处理树形...
然而,对于递归查询而言,更常用的方法是使用存储过程或者递归临时表。 **示例**: - 创建一个简单的部门表并插入数据。 - 使用存储过程实现递归查询。 **创建部门表**: ```sql DROP TABLE IF EXISTS `dept`; ...
- 在`tas`临时表的基础上继续进行递归查询,指定递归深度不超过2层。 - 使用`START WITH`指定起始节点的`cant_code`为'16'。 - 最终结果按`cant_note`, `super_code`, `super_codex`, `cant_code`排序。 #### ...
DB2递归实现使用逐层递归(广度优先)方法,而Oracle递归实现使用深度优先方法。 在本文中,我们将使用一个实用的例子来描述如何将CONNECT BY和相关的伪列映射到DB2递归。我们将定义和填充一个雇员表,然后使用递归...
递归查询用于查询父子节点结构的数据表,形成树状结构的数据集,常用于菜单数据集、报表结构数据。HANA 和 Oracle 中的递归查询语句都是使用 start with…connect by prior 语句实现的。然而,HANA 中没有 level、...
Oracle的物化视图在MySQL中没有直接对应的概念,可能需要通过创建临时表或定期更新的视图来实现类似功能。 10. **索引优化**: Oracle支持位图索引、函数索引等高级特性,MySQL则相对较简单,但也有覆盖索引、...
`WITH` 临时表在复杂的查询中尤其有用,可以用来简化SQL语句,使得SQL更加易于理解和维护。 **语法结构:** ```sql WITH temp_table_name (column1, column2, ...) AS ( SELECT column1, column2, ... FROM some_...
通过提示及配置文件等来控制执行计划; 在程序中优化查询而无需改动代码。 作为Oracle SQL经典著作之一,本书为SQL开发人员指明了前行的方向,赋予了他们不断开拓的动力。 作者简介 KAREN MORTON 研究...
这种方法包括创建一个与原表结构相同的临时表,然后将原表重命名为带有时间戳的新名,最后将临时表重命名为原表名。在OLTP系统中,由于可能存在的DML操作,重命名操作可能会遇到`ORA-00054: resource busy`的错误,...
首先,创建一个存储过程 `sp_getChildNodes`,该过程将递归地查找所有子节点,并将结果存储在一个临时表中。然后,使用该临时表来查找所有子节点。 创建 `sp_getChildNodes` 存储过程的 SQL 语句如下: ```sql ...
在这里,我们使用了`WITH`子句创建了一个带有级别的临时表,然后筛选出与ID为401000501同级别的节点。 6. **查询某节点的父节点及兄弟节点(叔伯节点)** 这个查询相对复杂,分为两部分: - 首先找到父节点的...
3. **递归查询优化**:当查询涉及多个表关联时,可以通过创建临时表并将其转化为多步操作来提高性能。 #### 三、SQL函数与表关联 - **尽量避免使用复杂的函数**:在WHERE子句中使用函数可能会导致索引失效,从而...
通过上述知识点,我们可以了解到在Oracle数据库中,I/O性能问题通常和数据的存储方式、查询的执行计划及系统的资源利用情况紧密相关。优化I/O性能不仅仅是一门技术,它还需要综合考虑整个数据库系统的运行环境和业务...
- Oracle支持`WITH`子句进行预查询,而HANA不支持这个功能,这意味着在HANA中可能需要使用临时表或嵌套查询来达到类似的效果。 7. **UPDATE语句** - 更新数据表的语法在HANA和Oracle中基本一致,都能直接对单一表...
- **硬解析过多:** 每次执行相同的SQL语句时都需要重新解析,而非复用已有的执行计划。 - **共享池内存消耗:** 大量不同的SQL文本占用更多的内存空间,影响系统的响应时间和可伸缩性。 **使用方法:** - 在SQL...
1. **创建临时表**:首先,创建了一个名为`Tt`的临时表,具有两列`ID`和`NAME`。然而,在这个例子中,创建表的命令后跟着一个注释,实际的创建过程可能已经完成,这里只是示例代码的一部分。 2. **生成行号**:通过...