Search notes:

Oracle SQL: CROSS APPLY

A cross apply join is a variation of the ANSI cross join.
As per an answer on asktom, Oracle supports cross apply in order to improve compatibility with other database products, noteably to

Example

Create tables …
create table tq84_left (
   id    integer primary key,
   text  varchar2(3) not null
);

create table tq84_right (
   id_left  integer not null references tq84_left,
   val      number(5,2)
);
Github repository Oracle-patterns, path: /SQL/select/join/apply/cross/ex-1/tables.sql
… fill them with some data …
insert into tq84_left values (1, 'foo');
insert into tq84_left values (2, 'bar');
insert into tq84_left values (3, 'baz');

insert into tq84_right values (1,   1.01);
insert into tq84_right values (1,  10.10);
insert into tq84_right values (1, 100.00);

insert into tq84_right values (2, 222.22);

insert into tq84_right values (3, 300.12);
insert into tq84_right values (3,  33.21);

commit;
Github repository Oracle-patterns, path: /SQL/select/join/apply/cross/ex-1/data.sql
… and then use cross apply to select from them.
Note that the join condition is formulated within the subquery, not after it:
select
   l.text,
   a.total
from
   tq84_left l cross apply
  (select
      sum(r.val) total
   from
      tq84_right r
   where
      r.id_left = l.id
  ) a;
--
-- foo	111.11
-- bar	222.22
-- baz	333.33
Github repository Oracle-patterns, path: /SQL/select/join/apply/cross/ex-1/select.sql
Show the SQL execution plan
explain plan for
select
   l.text,
   a.total
from
   tq84_left l cross apply
  (select
      sum(r.val) total
   from
      tq84_right r
   where
      r.id_left = l.id
  ) a;

select * from table(dbms_xplan.display);
--
-- ----------------------------------------------------------------------------------------
-- | Id  | Operation            | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
-- ----------------------------------------------------------------------------------------
-- |   0 | SELECT STATEMENT     |                 |     6 |   282 |     7  (15)| 00:00:01 |
-- |*  1 |  HASH JOIN OUTER     |                 |     6 |   282 |     7  (15)| 00:00:01 |
-- |   2 |   TABLE ACCESS FULL  | TQ84_LEFT       |     3 |    63 |     3   (0)| 00:00:01 |
-- |   3 |   VIEW               | VW_DCL_535DE542 |     6 |   156 |     4  (25)| 00:00:01 |
-- |   4 |    HASH GROUP BY     |                 |     6 |   156 |     4  (25)| 00:00:01 |
-- |   5 |     TABLE ACCESS FULL| TQ84_RIGHT      |     6 |   156 |     3   (0)| 00:00:01 |
-- ----------------------------------------------------------------------------------------
Github repository Oracle-patterns, path: /SQL/select/join/apply/cross/ex-1/explain-plan.sql
Show the execution plan of an SQL statement that uses left join rather than cross apply. Such an SQL statement produces the same result, but uses a different execution plan:
explain plan for
select
   l.text,
   sum(r.val) total
from
   tq84_left  l                      left join
   tq84_right r on l.id = r.id_left
group by
   l.text;

select * from table(dbms_xplan.display);
--
-- ----------------------------------------------------------------------------------
-- | Id  | Operation           | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
-- ----------------------------------------------------------------------------------
-- |   0 | SELECT STATEMENT    |            |     6 |   282 |     7  (15)| 00:00:01 |
-- |   1 |  HASH GROUP BY      |            |     6 |   282 |     7  (15)| 00:00:01 |
-- |*  2 |   HASH JOIN OUTER   |            |     6 |   282 |     6   (0)| 00:00:01 |
-- |   3 |    TABLE ACCESS FULL| TQ84_LEFT  |     3 |    63 |     3   (0)| 00:00:01 |
-- |   4 |    TABLE ACCESS FULL| TQ84_RIGHT |     6 |   156 |     3   (0)| 00:00:01 |
-- ----------------------------------------------------------------------------------
Github repository Oracle-patterns, path: /SQL/select/join/apply/cross/ex-1/explain-plan-join.sql

See also

An outer apply is to cross apply what an left outer join is to a join.
Oracle SQL: joins
Lateral inline views
SQL Server: cross apply / outer apply

Index