Sei sulla pagina 1di 1

Chapter 3: Selecting 117

INSERT t2 VALUES ( 11, 999 );


INSERT t2 VALUES ( 22, 50 );
COMMIT;

SELECT *
FROM t1
WHERE t1.non_key_1 = ANY ( SELECT t2.non_key_1 / 10
FROM t2 );
Heres how that WHERE clause works, at least logically: For each row returned
by the FROM t1 clause, the single-column subquery ( SELECT t2.non_key_1 /
10 FROM t2 ) is evaluated and searched to determine if one or more values are
equal to t1.non_key_1. That comparison yields FALSE for one of the rows in t1,
and TRUE for the other one. Heres the final result set:
key_1 non_key_1
===== =========
3 5
The query optimizer doesnt actually do it that way. In fact, the whole select is
turned into a join and the subquery is completely eliminated. You can see this
for yourself by putting the select inside a string literal and passing it to the
REWRITE function as follows:
SELECT REWRITE ( '
SELECT *
FROM t1
WHERE t1.non_key_1 = ANY ( SELECT t2.non_key_1 / 10
FROM t2 )' );
The REWRITE function shows you what the query optimizer does with your
select; heres what it says in this case:
SELECT DISTINCT
t1_1.key_1,
t1_1.non_key_1
FROM t2 as t2_1,
t1 as t1_1
WHERE t1_1.non_key_1 = t2_1.non_key_1 / 10;
The query optimizer rewrites queries for performance. Thats good, because it
means you can write your WHERE clauses in a way that makes sense to you;
for example, if you want to use a subquery with the ANY quantifier, go ahead.
Dont worry about performance, and dont struggle changing subqueries into
joins.

3.12.2 EXISTS Predicates


The second kind of predicate is a test to see if any rows exist in a subquery:
<exists_predicate> ::= EXISTS "(" <query_expression> ")"
The exists predicate is especially useful with foreign key relationships. You can
use it to find parent table rows that do, or do not, have any corresponding rows
in a child table. Here is an example that shows which rows in the parent t1 have
any corresponding rows in the child table t2, without actually displaying any
data from t2:
CREATE TABLE t1 (
key_1 INTEGER NOT NULL PRIMARY KEY,
non_key_1 INTEGER NOT NULL );

Potrebbero piacerti anche