WITH
alias_name -- Alias to use in the main query
AS
(insert a query here)
SELECT... -- Beginning of the query main body
Multiple aliases can be defined in the WITH clause:
WITH
alias_name1
AS
(query1)
aleas_name2
AS
(query2)
...
SELECT...
Let's look inside by taking a simple query:
SQL> col dummy format a10;
SQL> select dummy from dual;
DUMMY
----------
X
SQL>
Same re-written as WITH clause will be:
SQL> with d as (select * from dual)
2 select * from d;
DUMMY
----------
X
SQL>
Even if it seems nonsense at first glance, using WITH clause in complicated queries could be very worthy.
SQL> with temp_t1 as ( select dummy c1 from dual
2 select * from temp_t1 a,temp_t1 b
3 /
C1 C1
-- --
X X
SQL> with temp_t1 as (select dummy c1 from dual)
2 ,temp_t2 as (select dummy c1 from dual)
3 select * from temp_t1 a,temp_t2 b
4 /
C1 C1
-- --
X X
SQL> with temp_t1 as ( select dummy c1 from dual )
2 ,temp_t2 as ( select dummy c1 from dual a,temp_t1 b where b.c1 = a.dummy )
3 select * from temp_t2 a
4 /
C1
--
X
SQL> select * from temp_t2 a;
select * from temp_t2 a
ORA-00942: table or view does not exist
So nevertheless we can select the recordset as a table it exists actually only during the execution.
SELECT dname, SUM(sal) AS dept_total FROM emp, dept
WHERE emp.deptno = dept.deptno
GROUP BY dname HAVING
SUM(sal) > ( SELECT SUM(sal) * 1/3 FROM emp, dept
WHERE emp.deptno = dept.deptno)
ORDER BY SUM(sal) DESC;
WITH summary AS
(
SELECT dname, SUM(sal) AS dept_total FROM emp, dept
WHERE emp.deptno = dept.deptno
GROUP BY dname
)
SELECT dname, dept_total FROM summary
WHERE dept_total > (SELECT SUM(dept_total) * 1/3 FROM summary)
ORDER BY dept_total DESC;
CREATE TABLE TestTbl
NOLOGGING
AS
SELECT A1.OWNER AS usr
,A1.OBJECT_TYPE AS PROD
,A1.OBJECT_ID AS ITEMS
FROM ALL_OBJECTS A1, EMP A2, DEPT A3;
SQL> select count(*) as recs from testtbl;
RECS
----------
3140928
SQL> exec DBMS_STATS.GATHER_TABLE_STATS(USER,'TESTTBL');
PL/SQL procedure successfully completed
SQL>
set serveroutput on;
set autotrace on;
set timing on;
SQL> SELECT prod
2 ,total_items
3 FROM (
4 SELECT prod
5 , NVL(SUM(items),0) AS total_items
6 FROM testtbl
7 GROUP BY
8 prod
9 ) ilv
10 WHERE total_items > (SELECT SUM(items)/3 AS one_third_items
11* FROM testtbl)
SQL> /
PROD TOTAL_ITEMS
------------------- ----------------------
SYNONYM 50068277560
JAVA CLASS 43610562520
Elapsed: 00:00:03.07
Execution Plan
----------------------------------------------------------
Plan hash value: 2449639557
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 28 | 3154 (8)| 00:00:38 |
|* 1 | FILTER | | | | | |
| 2 | HASH GROUP BY | | 2 | 28 | 3154 (8)| 00:00:38 |
| 3 | TABLE ACCESS FULL| TESTTBL | 3140K| 41M| 2967 (2)| 00:00:36 |
| 4 | SORT AGGREGATE | | 1 | 5 | | |
| 5 | TABLE ACCESS FULL| TESTTBL | 3140K| 14M| 2967 (2)| 00:00:36 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(NVL(SUM("ITEMS"),0)> (SELECT SUM("ITEMS")/3 FROM
"TESTTBL" "TESTTBL"))
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
21319 consistent gets
21213 physical reads
0 redo size
536 bytes sent via SQL*Net to client
381 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
2 rows processed
SQL>
SQL> WITH ITEMS_REP AS (
2 SELECT PROD, NVL(SUM(ITEMS),0) AS TOTAL_ITMES
3 FROM TESTTBL
4 GROUP BY PROD)
5 SELECT PROD, TOTAL_ITMES
6 FROM ITEMS_REP
7 WHERE TOTAL_ITMES > (SELECT SUM(TOTAL_ITMES)/3 AS ONE_THIRD_ITEMS
8 FROM ITEMS_REP)
9/
SQL>
PROD TOTAL_ITMES
------------------- -----------
SYNONYM 50068277560
JAVA CLASS 43610562520
Elapsed: 00:00:02.15
Execution Plan
----------------------------------------------------------
Plan hash value: 2967744285
-------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 22 | 528 | 3158 (8)| 00:00:38 |
| 1 | TEMP TABLE TRANSFORMATION | | | | | |
| 2 | LOAD AS SELECT | | | | | |
| 3 | HASH GROUP BY | | 22 | 308 | 3154 (8)| 00:00:38 |
| 4 | TABLE ACCESS FULL | TESTTBL | 3140K| 41M| 2967 (2)| 00:00:36 |
|* 5 | VIEW | | 22 | 528 | 2 (0)| 00:00:01 |
| 6 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6633_E00F1 | 22 | 308 | 2 (0)| 00:00:01 |
| 7 | SORT AGGREGATE | | 1 | 13 | | |
| 8 | VIEW | | 22 | 286 | 2 (0)| 00:00:01 |
| 9 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6633_E00F1 | 22 | 308 | 2 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - filter("TOTAL_ITMES"> (SELECT SUM("TOTAL_ITMES")/3 FROM (SELECT /*+ CACHE_TEMP_TABLE
("T1") */ "C0" "PROD","C1" "TOTAL_ITMES" FROM "SYS"."SYS_TEMP_0FD9D6633_E00F1" "T1")
"ITEMS_REP"))
Statistics
----------------------------------------------------------
2 recursive calls
9 db block gets
10672 consistent gets
10613 physical reads
644 redo size
536 bytes sent via SQL*Net to client
381 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
2 rows processed
SQL> EXPLAIN PLAN SET STATEMENT_ID = 'SQ_FCT' for
2 WITH ITEMS_REP AS (
3 SELECT PROD, NVL(SUM(ITEMS),0) AS TOTAL_ITMES
4 FROM TESTTBL
5 GROUP BY PROD)
6 SELECT PROD, TOTAL_ITMES
7 FROM ITEMS_REP
8 WHERE TOTAL_ITMES > (SELECT SUM(TOTAL_ITMES)/3 AS ONE_THIRD_ITEMS
9 FROM ITEMS_REP);
SQL>
SQL> @?RDBMS\ADMIN\utlxplp.sql
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 395517267
-------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 22 | 528 | 3158 (8)| 00:00:38 |
| 1 | TEMP TABLE TRANSFORMATION | | | | | |
| 2 | LOAD AS SELECT | | | | | |
| 3 | HASH GROUP BY | | 22 | 308 | 3154 (8)| 00:00:38 |
| 4 | TABLE ACCESS FULL | TESTTBL | 3140K| 41M| 2967 (2)| 00:00:36 |
|* 5 | VIEW | | 22 | 528 | 2 (0)| 00:00:01 |
| 6 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6637_E00F1 | 22 | 308 | 2 (0)| 00:00:01 |
| 7 | SORT AGGREGATE | | 1 | 13 | | |
| 8 | VIEW | | 22 | 286 | 2 (0)| 00:00:01 |
| 9 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6637_E00F1 | 22 | 308 | 2 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------
SQL> set autotrace traceonly explain
SQL>
SQL> WITH INLINE_VIEW AS (
2 SELECT PROD
3 , SUM(ITEMS) AS TOTAL_ITEMS
4 FROM testtbl
5 GROUP BY PROD
6 )
7 SELECT *
8 FROM inline_view;
Execution Plan
----------------------------------------------------------
Plan hash value: 1165785812
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 22 | 308 | 3154 (8)| 00:00:38 |
| 1 | HASH GROUP BY | | 22 | 308 | 3154 (8)| 00:00:38 |
| 2 | TABLE ACCESS FULL| TESTTBL | 3140K| 41M| 2967 (2)| 00:00:36 |
------------------------------------------------------------------------------
SQL>
SQL> WITH INLINE_VIEW AS (
2 SELECT /*+ materialize */
3 PROD, SUM(ITEMS) AS TOTAL_ITEMS
4 FROM testtbl
5 GROUP BY PROD
6 )
7 SELECT *
8 FROM inline_view;
Execution Plan
----------------------------------------------------------
Plan hash value: 844976587
-------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 22 | 528 | 3156 (8)| 00:00:38 |
| 1 | TEMP TABLE TRANSFORMATION | | | | | |
| 2 | LOAD AS SELECT | | | | | |
| 3 | HASH GROUP BY | | 22 | 308 | 3154 (8)| 00:00:38 |
| 4 | TABLE ACCESS FULL | TESTTBL | 3140K| 41M| 2967 (2)| 00:00:36 |
| 5 | VIEW | | 22 | 528 | 2 (0)| 00:00:01 |
| 6 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6639_E00F1 | 22 | 308 | 2 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------
SQL>
INSERT INTO table_name
WITH subquery_name AS (SELECT . . .)
SELECT ... FROM subquery_name;
UPDATE table_name
SET column_name = ( WITH subquery_name AS (SELECT ...)
SELECT ... FROM subquery_name );
DELETE FROM table_name
WHERE column_name IN ( WITH subquery_name AS (SELECT ...)
SELECT ... FROM subquery_name );
SELECT * FROM v$version;
WITH T1 AS (SELECT * FROM DUAL),
T2 AS (SELECT * FROM DUAL)
select * from t1;
BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.7.0 - Production
PL/SQL Release 9.2.0.7.0 - Production
CORE 9.2.0.7.0 Production
TNS for 32-bit Windows: Version 9.2.0.7.0 - Production
NLSRTL Version 9.2.0.7.0 - Production
Error starting at line 2 in command:
WITH T1 AS (SELECT * FROM DUAL),
T2 AS (SELECT * FROM DUAL)
select * from t1
Error at Command Line:4 Column:14
Error report:
SQL Error: ORA-32035: unreferenced query name defined in WITH clause
32035. 00000 - "unreferenced query name defined in WITH clause"
*Cause: There is at least one WITH clause query name that is not
referenced in any place.
*Action: remove the unreferenced query name and retry
SELECT * FROM v$version;
WITH T1 AS (SELECT * FROM DUAL),
T2 AS (SELECT * FROM DUAL)
select * from t1;
BANNER
---------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - Production
PL/SQL Release 11.1.0.7.0 - Production
CORE 11.1.0.7.0 Production
TNS for 32-bit Windows: Version 11.1.0.7.0 - Production
NLSRTL Version 11.1.0.7.0 - Production
DUMMY
-----
X
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (1)
Commented:
Suggestion: Can you include Flushing of Shared_Pool and buffer_cache in order to reflect more acurate result for Consistent and Physical IO also?