05.11.2015 Views

Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

CHAPTER 1 ■ DEVELOPING SUCCESSFUL ORACLE APPLICATIONS 37<br />

They needed to be able to report on the parent record with aggregates from each of the<br />

child tables. The databases they worked with in the past did not support subquery factoring<br />

(WITH clause), nor did they support inline views, the ability to “query a query” instead of query<br />

a table. Not knowing these features existed, the developers wrote their own database of sorts<br />

in the middle tier. They would query the parent table <strong>and</strong> for each row returned run an aggregate<br />

query against each of the child tables. This resulted in their running thous<strong>and</strong>s of queries<br />

for each single query the end user wanted to run. Or, they would fetch the entire aggregated<br />

child tables into their middle tier into hash tables in memory—<strong>and</strong> do a hash join.<br />

In short, they were reinventing the database, performing the functional equivalent of a<br />

nested loops join or a hash join, without the benefit of temporary tablespaces, sophisticated<br />

query optimizers, <strong>and</strong> the like. They were spending their time developing, designing, finetuning,<br />

<strong>and</strong> enhancing software that was trying to do the same thing the database they already<br />

bought did! Meanwhile, end users were asking for new features but not getting them, because<br />

the bulk of the development time was in this reporting “engine,” which really was a database<br />

engine in disguise.<br />

I showed them that they could do things such as join two aggregations together, in<br />

order to compare data that was stored at different levels of detail in many different ways<br />

(see Listings 1-1 through 1-3).<br />

Listing 1-1. Inline Views: Query from a “Query”<br />

select p.id, c1_sum1, c2_sum2<br />

from p,<br />

(select id, sum(q1) c1_sum1<br />

from c1<br />

group by id) c1,<br />

(select id, sum(q2) c2_sum2<br />

from c2<br />

group by id) c2<br />

where p.id = c1.id<br />

<strong>and</strong> p.id = c2.id<br />

/<br />

Listing 1-2. Scalar Subqueries: Run Another Query per Row<br />

select p.id,<br />

(select sum(q1) from c1 where c1.id = p.id) c1_sum1,<br />

(select sum(q2) from c2 where c2.id = p.id) c2_sum2<br />

from p<br />

where p.name = '1234'<br />

/<br />

Listing 1-3. WITH Subquery Factoring<br />

with c1_vw as<br />

(select id, sum(q1) c1_sum1<br />

from c1

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!