We could have written the same query with a slightly different syntax.
This construct is called a factored subquery (or subquery factoring).
WITH g AS (select x.deptno , avg(x.msal) avg_sal from emp x group by x.deptno) select e.ename, e.init, e.msal from emp e join g using (deptno) where e.msal > g.avg_sal;
Here, we have isolated the subquery definition from the actual query.
This makes the structure of the main query clearer.
Using the WITH clause syntax becomes even more attractive if you refer multiple times to the same subquery from the main query.
You can define as many subqueries as you like in a single WITH clause, separated by commas.
WITH v1 AS (select ... from ...) , v2 AS (select ... from ...) , v3 AS ... select ... from ...
SQL> SQL> drop table emp; Table dropped.-- ww w . j av a2 s.c o m SQL> create table emp( 2 empno NUMBER(4) primary key, 3 ename VARCHAR2(8) not null , 4 init VARCHAR2(5) not null , 5 job VARCHAR2(8) , 6 mgr NUMBER(4) , 7 bdate DATE not null , 8 msal NUMBER(6,2) not null , 9 comm NUMBER(6,2) , 10 deptno NUMBER(2) default 10) ; SQL> SQL> insert into emp values(7001,'SMITH','N', 'TRAINER', 7902,date '1975-12-17', 1800 , NULL, 20); SQL> insert into emp values(7002,'ALLEN','JAM','SALESREP',7006,date '1971-05-20', 1600, 300, 30); SQL> insert into emp values(7003,'WARD', 'TF' ,'SALESREP',7006,date '1972-03-02', 1250, 500, 10); SQL> insert into emp values(7004,'JACK', 'JM', 'MANAGER', 7009,date '1977-04-02', 2975, NULL, 20); SQL> insert into emp values(7005,'BROWN','P', 'SALESREP',7006,date '1976-09-28', 1250, 1400, 30); SQL> insert into emp values(7006,'BLAKE','R', 'MANAGER', 7009,date '1973-11-01', 2850, NULL, 10); SQL> insert into emp values(7007,'CLARK','AB', 'MANAGER', 7009,date '1975-06-09', 2450, NULL, 10); SQL> insert into emp values(7008,'SCOTT','DEF','TRAINER', 7004,date '1979-11-26', 3000, NULL, 20); SQL> insert into emp values(7009,'KING', 'CC', 'DIRECTOR',NULL,date '1972-10-17', 5000, NULL, 10); SQL> insert into emp values(7010,'BREAD','JJ', 'SALESREP',7006,date '1978-09-28', 1500, 0, 30); SQL> insert into emp values(7011,'ADAMS','AA', 'TRAINER', 7008,date '1976-12-30', 1100, NULL, 20); SQL> insert into emp values(7012,'JONES','R', 'ADMIN', 7006,date '1979-10-03', 8000, NULL, 30); SQL> insert into emp values(7902,'FORD', 'MG', 'TRAINER', 7004,date '1979-02-13', 3000, NULL, 20); SQL> insert into emp values(7934,'MARY', 'ABC','ADMIN', 7007,date '1972-01-23', 1300, NULL, 10); SQL> SQL> WITH g AS 2 (select x.deptno 3 , avg(x.msal) avg_sal 4 from emp x 5 group by x.deptno) 6 select e.ename, e.init, e.msal 7 from emp e 8 join g 9 using (deptno) 10 where e.msal > g.avg_sal; ENAME | INIT | MSAL -------- | ----- | --------- JONES | R | 08000.00 FORD | MG | 03000.00 SCOTT | DEF | 03000.00 JACK | JM | 02975.00 KING | CC | 05000.00 BLAKE | R | 02850.00 6 rows selected. SQL>