See the result in Figure 12.2.SELECT SONG_ID, GUESTARTIST_ID, INSTRUMENT_ID FROM INSTRUMENTATION WHERE INSTRUMENT_ID = SELECT INSTRUMENT_ID FROM INSTRUMENT WHERE NAME = 'Acoustic Guitar'
Trang 1270 12.4 Demonstrating Subqueries
A subquery itself is generally syntactically equivalent to a SELECT ment Chapters 4, 5, 6, and 11 apply to subqueries in this respect
state-So far in this chapter, we have seen a lot of information The easiest way
to explain subqueries is simply to demonstrate
Inline views or FROM clause embedded subqueries
Subqueries can be used in numerous SQL code commands and theirsubset clauses
A single-row subquery is exactly as its name implies: a subquery that returns
a single row If more than one row is returned, an error will result 01427: single-row subquery returns more than one row) Simple (equality),LIKE, and Range (BETWEEN) comparison conditions are restricted tosingle-row subquery results See the syntax diagram in Figure 12.1
(ORA-Figure 12.1
Subquery Comparison
Condition Syntax.
Chap12.fm Page 270 Thursday, July 29, 2004 10:09 PM
Trang 2Following is an example of a single-row subquery The ROWNUMpseudocolumn is used to restrict the subquery to a single row no matterhow many rows it returns See the result in Figure 12.2.
SELECT SONG_ID, GUESTARTIST_ID, INSTRUMENT_ID FROM INSTRUMENTATION WHERE INSTRUMENT_ID = (SELECT INSTRUMENT_ID FROM INSTRUMENT WHERE NAME = 'Acoustic Guitar');
In the next example, the query in Figure 12.2 is altered to ensure thatmultiple rows are returned from the subquery Removing the WHEREclause filter from the query in Figure 12.2 results in an error, as shown inFigure 12.3 The subquery in Figure 12.3 returns all rows in the INSTRU-MENT table
Figure 12.2
A Single-Row Subquery.
Chap12.fm Page 271 Thursday, July 29, 2004 10:09 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 3272 12.4 Demonstrating Subqueries
A multiple-row subquery returns multiple rows The IN, EXISTS, andGroup (ANY, ALL, SOME) comparison conditions allow multiple-rowsubquery results See the syntax diagram in Figure 12.1
A multiple-row subquery can provide the set of values needed for the
IN comparison condition
The EXISTS comparison condition usually uses indexes to matchvalues in the subquery to values in the calling query Regardless ofcorrelated indexed columns between calling and subquery, EXISTSwill stop execution of the subquery when the appropriate value isfound IN will build all values in the set for the subquery before pass-ing its result back to the calling query Using EXISTS rather than INoften results in better performance of the query EXISTS may notperform better than IN when the set produced by the subquery is alimited set of literal values or a very small number of rows
ANY, ALL, and SOME imply any value, all values, and some values,respectively Because these subquery comparison conditions testagainst a set of values, a multiple-row query can in reality return zero,one, or many rows
rows because the Membership, Exists, and Group comparison conditionsreturn a set of values That set of values can be an empty set An empty set is avalid set
Figure 12.3
A Single-Row
Subquery Returning More
Than One Row
Returns an Error.
Chap12.fm Page 272 Thursday, July 29, 2004 10:09 PM
Trang 412.4 Demonstrating Subqueries 273
Chapter 12
Following are some multiple-row subquery examples, perhaps allowing for
a better understanding of multiple-row subquery comparison conditions.This query returns the names of all instruments in the INSTRUMENTtable that are used by artists doing guest appearances The subquery is a reg-ular (noncorrelated) multiple-row subquery using the IN comparison con-dition The result is shown in Figure 12.4
SELECT NAME FROM INSTRUMENT WHERE INSTRUMENT_ID IN (SELECT INSTRUMENT_ID FROM INSTRUMENTATION);
This query returns the name of instruments played when ARTIST_ID
of 1 made a guest appearance Because ARTIST_ID 1 made no guestappearances on any songs, no rows are returned by the subquery Thisshows that a subquery returning a NULL set of rows is valid The subquery
is a regular, multiple-row subquery using the IN comparison condition.The result is shown in Figure 12.5
SELECT NAME FROM INSTRUMENT WHERE INSTRUMENT_ID IN (SELECT INSTRUMENT_ID FROM INSTRUMENTATION
WHERE GUESTARTIST_ID = 1);
Figure 12.4
The IN Comparison Condition.
Chap12.fm Page 273 Thursday, July 29, 2004 10:09 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 5274 12.4 Demonstrating Subqueries
This query lists artists who never made guest appearances on any songs
The subquery is a correlated multiple-row subquery and uses the NOTEXISTS comparison condition The result is shown in Figure 12.6
SELECT NAME FROM ARTIST A WHERE NOT EXISTS (SELECT GA.GUESTARTIST_ID
FROM GUESTAPPEARANCE GA WHERE GA.GUESTARTIST_ID = A.ARTIST_ID);
This query returns the names of artists who recorded songs before May
1, 2001 The subquery is a regular multiple-row subquery using the ANYcomparison condition If you want to list the recording date in your queryresults, you must use a join or a FROM clause subquery The result isshown in Figure 12.7
SELECT NAME FROM ARTIST A WHERE A.ARTIST_ID = ANY (SELECT S.ARTIST_ID FROM SONG S
WHERE S.RECORDING_DATE < '01-MAY-2001');
This query returns the titles of CDs that have songs with a guest ance The subquery is a regular multiple-row subquery using the SOMEcomparison condition (SOME is identical to ANY) The result is shown inFigure 12.8
appear-Figure 12.5
The IN Comparison
Trang 612.4 Demonstrating Subqueries 275
Chapter 12
SELECT DISTINCT M.TITLE FROM MUSICCD M JOIN CDTRACK CT ON (M.MUSICCD_ID = CT.MUSICCD_ID) WHERE CT.SONG_ID = SOME
(SELECT SONG_ID FROM GUESTAPPEARANCE GA);
Figure 12.6
NOT EXISTS with a Correlated
Subquery.
Figure 12.7
= ANY with a Subquery.
Chap12.fm Page 275 Thursday, July 29, 2004 10:09 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 7276 12.4 Demonstrating Subqueries
This example returns the names of artists who have not been in the dio after January 1, 2000 The subquery is a correlated multiple-row sub-query using the ALL comparison condition
stu-Note: Note: If you want to list the session date in your query results, youmust use a join or a FROM clause subquery (inline view) instead of a sub-query in the WHERE clause
The result is shown in Figure 12.9
SELECT A.NAME FROM ARTIST A WHERE '01-JAN-2000' > ALL (SELECT ST.SESSION_DATE FROM STUDIOTIME ST
WHERE ST.ARTIST_ID = A.ARTIST_ID);
A multiple-column subquery can return a single or multiple rows It simplyreturns more than one column for each row Typically, a multiple-columnsubquery is used to validate a set of columns against another set of columns
in a WHERE clause or as a tuned FROM clause row filter (inline view), asshown in the two examples following
The first example following uses the IN set membership comparison tofind a row set of two columns from the ARTIST table where the name of the
Trang 812.4 Demonstrating Subqueries 277
Chapter 12
artist contains a lowercase letter “u” See the result in Figure 12.10 Noticethat the subquery SELECT clause contains two columns Notice also that thecalling query WHERE clause filter has a list, in parentheses, of two columnsthat are to be compared to the two columns returned by the subquery
SELECT A.ARTIST_ID, A.NAME, S.TITLE FROM ARTIST A, SONG S WHERE (A.ARTIST_ID, A.NAME) IN
(SELECT ARTIST_ID, NAME FROM ARTIST WHERE NAME LIKE '%u%') AND A.ARTIST_ID = S.ARTIST_ID;
The next and second example of a multiple-column subquery will duce the same result as shown in Figure 12.10 In Figure 12.11, an element
pro-of the FROM clause contains the same subquery as in the first example inFigure 12.10
Note: This example is better than the previous one for a very large ARTIST
table because the filter is executed before the join of the ARTIST rows withthe SONG rows The query will perform better because the join occurs on
a smaller number of rows.1
Figure 12.9
> ALL with a Subquery.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 1012.4 Demonstrating Subqueries 279
Chapter 12
This section discusses the pros and cons of using regular or correlated queries
sub-A correlated subquery allows the correlation or matching of a columnbetween a calling query and a subquery The calling query can pass analiased column name into the subquery, not the other way around Queriesare parsed from left to right and from top to bottom The SQL parser willnot understand what to do with an attempt to pass a column alias frombottom to top and will produce a syntax (SQL parse) error A subquery isparsed and executed before its calling query or subquery For example, thefollowing query has a SELECT clause that references a column from a cor-related subquery found in the WHERE clause The following query passesthe ARTIST_ID column value from the calling query into the subquery,matching each ARTIST table row with related STUDIOTIME table rows
SELECT A.NAME FROM ARTIST A WHERE '01-JAN-2000' > ALL (SELECT ST.SESSION_DATE FROM STUDIOTIME ST WHERE ST.ARTIST_ID = A.ARTIST_ID);
The most common use for correlated subqueries is using the EXISTScomparison condition as in the script shown following The ARTIST_IDcolumn value is passed from the calling query into the subquery A correla-
Figure 12.12
Values Can Be Passed from a Calling Query into
a Correlated Subquery.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 11SELECT NAME FROM ARTIST A WHERE EXISTS (SELECT GA.GUESTARTIST_ID
FROM GUESTAPPEARANCE GA WHERE GA.GUESTARTIST_ID = A.ARTIST_ID);
Regular subqueries maintain no relationship or correlation between thecalling query and the subquery A regular subquery will execute before thecalling query such that the calling query will operate on the result set pro-duced by the subquery You cannot reference any columns within the sub-query from the calling query For example, this query has a regularsubquery, a variation on the query in Figure 12.12 except excluding the cor-related columns, passed from the calling query into the subquery
SELECT S.RECORDING_DATE FROM SONG S WHERE S.RECORDING_DATE > ALL
(SELECT ST.SESSION_DATE FROM STUDIOTIME ST);
Regardless of when Oracle parses the subquery, the calling query cannotcontain references to any columns that belong to the subquery The onlyexception to this rule is when the subquery is in the FROM clause In thatcase, the subquery columns are available to the calling query and can beused in the SELECT and WHERE clauses of the calling query
A nested subquery is a subquery nested or buried within another subquery.For example, the following query has a nested subquery executed againstthe CDTRACK table, called from the subquery executed against the MUS-ICCD table The result is shown in Figure 12.13
SELECT GENRE FROM GENRE WHERE GENRE_ID IN (SELECT GENRE_ID FROM MUSICCD WHERE MUSICCD_ID IN (SELECT MUSICCD_ID FROM CDTRACK));
Trang 12Fig-SELECT G.GENRE_ID, M.TITLE, M.TRACK_SEQ_NO FROM GENRE G
, (SELECT MCD.GENRE_ID, MCD.TITLE, CD.TRACK_SEQ_NO FROM MUSICCD MCD
, (SELECT MUSICCD_ID, TRACK_SEQ_NO FROM CDTRACK) CD WHERE CD.MUSICCD_ID = MCD.MUSICCD_ID) M
WHERE M.GENRE_ID = G.GENRE_ID;
Figure 12.13
A Multilayer Nested Subquery.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 13282 12.4 Demonstrating Subqueries
The query in Figure 12.14 has many more rows than the query in Figure12.13 because Figure 12.14 retrieves the join between the three tables andFigure 12.13 represents on DISTINCT genres from the GENRE table
We have already seen that subqueries can be used in many places, cally speaking, as listed previously in this chapter
syntacti-Note: In Oracle Database 8i, use of subqueries was limited In Oracle
Data-base 9i and Oracle DataData-base 10g, restrictions are almost completely lifted.
Two significant uses of subqueries not covered in this chapter so far areDML command subqueries, as in the INSERT and UPDATE statements.Placing subqueries in the VALUES clause of an INSERT statement and inUPDATE statements can be useful Be aware of performance impact whenusing subqueries in ORDER BY clauses, CASE statement expressions, theSPREADSHEET clause, and as function parameters Here is an example of
an INSERT statement with a subquery that returns the ARTIST_ID of
Trang 14UPDATE SONG SET PLAYING_TIME = (SELECT PLAYING_TIME FROM SONG WHERE TITLE = 'Safe And Sound') WHERE TITLE = 'Where are you?';
Figure 12.15 shows the resulting inserted and subsequently updated rowfor Sheryl Crow
That completes this chapter on subqueries The next chapter looks atthe more unusual or less used query types, including composites, hierarchi-cal queries, flashback versions, and parallel queries
Figure 12.15
Subqueries in INSERT and UPDATE Statements.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 15284 12.5 Endnotes
1 Oracle Performance Tuning for 9i and 10g (ISBN: 1-55558-305-9)
Trang 1613
Unusual Query Types
In this chapter:
What is a composite query and what are set operators?
What is a hierarchical query?
What are versions queries and what is flashback?
What are parallel queries?
Unusual query types are detailed in this chapter because they may berarely used On the other hand, certain types of queries do not really belong
in previous chapters because they are either so obscure or just too cated, until now We begin with composite queries
So what is a composite query? A composite query is simply a composite orconcatenation of two queries Special set operators are used to concatenatethe results of two separate queries There are certain restrictions, such as:both SELECT column sets in the two queries, must have the same number
of columns, and datatypes must be compatible, dependent on SELECTcolumn list position So what are the available set operators?
As already stated, set operators are used to combine two separate queriesinto a single result set
dupli-cates Duplicate rows are rows returned by both queries
Chap13.fm Page 285 Thursday, July 29, 2004 10:10 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 17286 13.1 Composite Queries
returned once In other words, duplicate rows are removed
intersec-tion is a little like an inner join
of a left outer join where only distinct rows in the first query arereturned
In order to demonstrate a sensible use of composite queries, let’s create aview, removing all styles from genres in the GENRES view Styles in theGENRE table are numbered as GENRE_ID 1, 2, and 3; the GENRESview will include only these rows
CREATE VIEW GENRES AS SELECT GENRE_ID AS ID, GENRE FROM GENRE WHERE STYLE_ID IS NOT NULL;
The following query concatenates the GENRE table and GENRESview We are trying to retrieve duplicated rows The resulting row countincludes all rows in the GENRE table and the GENRES view The result-ing duplicated rows can be clearly seen in Figure 13.1 The ORDER BYclause is used to show duplications (see Chapter 6)
SELECT GENRE_ID, GENRE FROM GENRE UNION ALL
SELECT * FROM GENRES ORDER BY 1;
Now let’s change the query in Figure 13.1 and remove the duplications
as in the following query using the UNION set operator instead of theUNION ALL operator The result is shown in Figure 13.2
SELECT GENRE_ID, GENRE FROM GENRE UNION
SELECT * FROM GENRES ORDER BY 1;
Chap13.fm Page 286 Thursday, July 29, 2004 10:10 PM
Trang 18SELECT GENRE_ID, GENRE FROM GENRE INTERSECT
SELECT * FROM GENRES;
In the next example, the MINUS operator is used to remove all genresfrom the GENRE table using the GENRES view, returning only GENREstyle rows 1, 2, and 3 The result is shown in Figure 13.4
SELECT GENRE_ID, GENRE FROM GENRE MINUS
SELECT * FROM GENRES;
Figure 13.1
Duplicating Rows
with UNION ALL.
Chap13.fm Page 287 Thursday, July 29, 2004 10:10 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 19288 13.1 Composite Queries
Figure 13.2
Removing Duplicates with
Trang 20we should examine (see Chapter 7).
pairs as opposed to only parent-child pairs In other words, pairs can bematched and returned where those pairs are not directly related within ahierarchy but related from the top to the bottom of a hierarchy
Figure 13.4
MINUS Returns
Rows in the First
Query Only.
Chap13.fm Page 289 Thursday, July 29, 2004 10:10 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 21290 13.2 Hierarchical Queries
subsequent expression for each parent row of each current row, using
a current row column to hook into a parent row column
of CONNECT BY PRIOR except using the root row of the chy as opposed to the parent row
clause) This returns the level (1, 2, etc.) of the row
These pseudocolumns determine if hierarchical data can be expandedupon Does an element have ancestor and/or child entries?
Now let’s demonstrate use of hierarchical queries
In this first example, PRIOR is used with the CONNECT BY conditionevaluating the subsequent expression for each parent row of each currentrow, using a current row column to hook into a parent row column Figure13.5 shows the result The START WITH modifier simply begins at a spe-cific point within the hierarchy
SELECT INSTRUMENT_ID, NAME, SECTION_ID, LEVEL FROM INSTRUMENT
START WITH INSTRUMENT_ID = 10 CONNECT BY PRIOR INSTRUMENT_ID = SECTION_ID ORDER BY 4, 2;
Notice in Figure 13.5 that the LEVEL column is included in the query.All the brass instruments are in the brass section The row Brass is thereforelevel 1 and the other rows, the brass instruments section, are all level 2.The following second example shows CONNECT_BY_ROOTperforming a similar function to that of CONNECT BY PRIOR exceptusing the root row of the hierarchy as opposed to the parent row The previ-ous query is changed, as shown with the result in Figure 13.6
SELECT CONNECT_BY_ROOT NAME "Section"
Chap13.fm Page 290 Thursday, July 29, 2004 10:10 PM
Trang 22
The third and fourth examples, shown next, demonstrate the use of the
ISLEAF pseudocolumns CONNECT_BY_ISCYCLE will return 1 if a rowhas a child where that child row is also an ancestor of the row Thus in thethird example shown following the result is 0 and no further rows areshown, because none are both children and ancestors at the same time Theresult is shown in Figure 13.7
SELECT CONNECT_BY_ISCYCLE “IsCycle”
, INSTRUMENT_ID, NAME, SECTION_ID, LEVEL FROM INSTRUMENT
START WITH INSTRUMENT_ID = 10 CONNECT BY NOCYCLE INSTRUMENT_ID = SECTION_ID ORDER BY 4, 2;
Figure 13.5
A Hierarchical Query on Hierarchical Data.
Chap13.fm Page 291 Thursday, July 29, 2004 10:10 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 23292 13.3 Flashback and Versions Queries
The CONNECT_BY_ISLEAF pseudocolumn returns a 1 when part ofthe CONNECT BY row set, indicating expansion possibilities.Thus for thefourth example, in the following query (the result in Figure 13.8), bothinstrument number 10 and its child instruments are shown However, onlyinstrument 10 has leaves; the other instruments are child rows, and theyhave no further children
SELECT CONNECT_BY_ISLEAF "IsLeaf"
, INSTRUMENT_ID, NAME, SECTION_ID, LEVEL FROM INSTRUMENT
START WITH INSTRUMENT_ID = 10 CONNECT BY PRIOR INSTRUMENT_ID = SECTION_ID ORDER BY 4, 2;
Next we look at flashback and versions queries
A flashback query literally allows flashing back to the state that data was in
at a previous point in time Oracle Database 9i allowed AS OF flashbackqueries back to a point in time using a timestamp or SCN Oracle Database
Figure 13.6
The CONNECT
_ BY_ROOT
Operator.
Chap13.fm Page 292 Thursday, July 29, 2004 10:10 PM
Trang 2413.3 Flashback and Versions Queries 293
Chapter 13
10g additionally allows what are called flashback versions queries A flashbackversions query can be used to return more than one version of a single rowboth before and after a change
desupported, will not support flashback queries
Figure 13.9 shows the syntax for flashback queries
queries at the session level
Figure 13.7
The CONNECT _BY_ ISCYCLE
Pseudocolumn.
Figure 13.8
The CONNECT _BY_ ISLEAF Pseudocolumn.
Chap13.fm Page 293 Thursday, July 29, 2004 10:10 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 25294 13.3 Flashback and Versions Queries
Several versions query pseudocolumns allow retrieval of identifying mation about different versions of the same row in a flashback query:
Now let’s look at some simple examples of flashback queries
First I add a new row to the CONTINENT table
INSERT INTO CONTINENT VALUES(CONTINENT_ID_SEQ.NEXTVAL , 'South East Asia');
Now I use an AS OF flashback query to look at all continents beforeinserting South East Asia Figure 13.10 shows that the row did not existyesterday
SELECT * FROM CONTINENT
AS OF TIMESTAMP(SYSTIMESTAMP - INTERVAL '1' DAY);
Figure 13.9
Flashback AS OF
and VERSIONS
Query Syntax.
Chap13.fm Page 294 Thursday, July 29, 2004 10:10 PM