You are on page 1of 3

With clause the with query_name clause lets you assign a name to a subquery block.

You can then reference the subquery block multiple places in the query by specifying the query name. Oracle optimizes the query by treating the query name as either an inline view or as a temporary table. you can specify this clause in any top-level select statement and in most types of subqueries. the query name is visible to the main query and to all subsequent subqueries except the subquery that defines the query name itself. a with clause is really best used when the result of the with query is required more than one time in the body of the query such as where one averaged value needs to be compared against two or three times. restrictions on subquery factoring: You cannot nest this clause. That is, you cannot specify the subquery_factoring_clause within the subquery of another subquery_factoring_clause. However, a query_name defined in one subquery_factoring_clause can be used in the subquery of any subsequent subquery_factoring_clause. In a query with set operators, the set operator subquery cannot contain the subquery_factoring_clause, but the from subquery can contain the subquery_factoring_clause. with <alias_name> as (subquery_sql_statement) select <column_name_list> from <alias>; with q as (select dummy from dual) select dummy from q; (corrected per notes from (colin hart and roy fraties) with <alias_one> as (subquery_sql_statement), <alias_two> as (sql_statement_from_alias_one) select <column_name_list> from <alias_one>, <alias_two> where <join_condition>; with qb1 as (select inst_id from gv$session),qb2 as(select unique inst_id from qb1 union all select unique inst_id from qb1) select /*+ materialize */ * from qb1, qb2 where qb1.inst_id = qb2.inst_id; explain plan for select per_h_email from person p where p.per_ok2_email = 'a' and p.per_h_email in ( select person_id from person where per_fmw = 'y') union select po_w_email from poie o where o.po_status = 'a' and o.po_w_email in ( select person_id from person where per_fmw = 'y'); select * from table(dbms_xplan.display); explain plan for with w as (

single alias double alias

with clause demos code from psoug fmw mailing list

select person_id from person where per_fmw = 'y') select per_h_email from person p, w where p.person_id = w.person_id and p.per_ok2_email = 'a' and p.per_h_email is not null union select po_w_email from poie o, w where o.person_id = w.person_id and o.po_status = 'a' and o.po_w_email is not null; with with connect by select * from table(dbms_xplan.display); built from code posted by michel cadot at comp.databases.oracle.misc 28-sep-2006 create table t1 ( pname varchar2(10), cases number(3)); insert into t1 values ('morgan',2); insert into t1 values ('dan',3); insert into t1 values ('jack',2); insert into t1 values ('helen',1); commit; select * from t1; create table t2 as select pname from t1 where 1=2; select * from t2; insert into t2 with rn as ( select rownum rn from dual connect by level <= (select max(cases) from t1)) select pname from t1, rn where rn <= cases order by pname; select * from t2; Another With Clause With Connect By From Michel Cadot Variable Liste varchar2(100) execute :liste := '5, 25, 41, 52'; with liste as ( select substr(:liste, instr(','||:liste||',', ',', 1, rn), instr(','||:liste||',', ',', 1, rn+1) instr(','||:liste||',', ',', 1, rn)-1) valeur from ( select rownum rn from dual

connect by level<=length(:liste) - length(replace(:liste,',',''))+1)) select trim(valeur) from liste; Another With Clause Demo Based On Code Posted By David Fitzjarrell At C.D.O.Server 01-Aug-2006 create table test ( job_id number(3), batch_id number(3), action varchar2(4), actdate date); insert into test values (1, 1, 'sent', sysdate-5); insert into test values (2, 1, 'recv', sysdate-4); insert into test values (3, 2, 'sent', sysdate-3); insert into test values (4, 2, 'recv', sysdate-2); insert into test values (5, 3, 'sent', sysdate-1); with col_generator as ( select t1.batch_id, decode(t1.action, 'sent', t1.actdate) sent, decode(t2.action,'recv', t2.actdate) received from test t1, test t2 where t2.batch_id(+) = t1.batch_id) select batch_id, max(sent) sent, max(received) received from col_generator group by batch_id order by 1; Another with clause demo posted by maxim demenko to comp.databases. Oracle.misc 3-mar-2008. This demo takes an input of numbers, in seconds and returns minutes:seconds. Col m:s format a10 with t as ( select 100 s from dual union all select 7201 from dual) select s,trunc(s/60)||':'||mod(s,60) "m:s" from t;