Chapter 7

Chapter 8 - Subqueries
 A Subquery
nests a SELECT statement in
the WHERE clause of another SELECT,
INSERT, UPDATE, or DELETE statement
 A Subquery’s Outer SELECT operates on
rows returned from the Inner SELECT
 The Inner and Outer SELECT statements
may refer to the same table
1
From the Inside Out
 Most
Subqueries are evaluated from the
inner query to the outer query
 A correlated Subquery, discussed later,
works in reverse
2
Simplified Subquery Syntax
 SELECT
select_list
FROM table_list
WHERE expression
{ [NOT] IN | operator | [NOT] EXISTS }
(SELECT subquery_select_list
FROM table_list
WHERE search_conditions);
3
Subquery Options
 Produces
an ‘IN’ list of values for
evaluation by the outer query
 Returns a single value for comparison
 Returns a TRUE/FALSE value for an
existence test
4
Why Use a Subquery?
 Subqueries
can be difficult to read
 Many can be replaced with an equivalent
join
 A subquery is sometimes the only
alternative
5
Example - without a Subquery
 Find
all the books that have the same price
as Straight Talk About Computers
 SELECT price
FROM titles
WHERE title = 'Straight Talk About
Computers';
 SELECT title, price
FROM titles
WHERE price = $19.99;
6
Example - Using a Subquery
 SELECT title,
price
FROM titles
WHERE price =
(SELECT price
FROM titles
WHERE title = 'Straight Talk About
Computers’);
7
Joins vs. Subqueries
 Join
– Advantages: Can return results from all tables
– Disadvantages: May need two statements to get
desired results
 Subquery
– Advantages: Can compare aggregates to other
values. Can get information in a single
statement
– Disadvantages: Can only return results from
the Outer Select statement
8
Two Ways
 SELECT pub_name,
au_lname
FROM publishers p, authors a
WHERE p.city = a.city;
 SELECT pub_name
FROM publishers
WHERE city IN
(SELECT city FROM authors);
9
The IN operator
 Use
the ‘IN’ operator when the results of
the inner query will have zero, one, or more
values
 Once the inner query returns results, the
outer query will make use of them
10
Example
 SELECT pub_name
FROM publishers
WHERE pub_id IN
(SELECT DISTINCT pub_id
FROM titles
WHERE type = 'business');
11
Conceptually...
 Inner
Query-
– SELECT DISTINCT pub_id
FROM titles
WHERE type = 'business';
(2 rows returned)
 Outer
Query Evaluates the 2 rows -
– SELECT pub_name
FROM publishers
WHERE pub_id IN ('1389', '0736');
12
Done as a Join
 SELECT DISTINCT pub_name,
title
FROM publishers p, titles t
WHERE p.pub_id = t.pub_id
AND type = 'business';
 With
Joins you can list columns from both
tables (see difference when title is left off
the select list)
13
Another Example as a Join
 Find
the names of all authors listed 2nd on
a book who live in California and receive
less than 30 percent of the royalties
 SELECT au_lname, au_fname
FROM authors a, titleauthors ta
WHERE state = 'CA'
AND a.au_id = ta.au_id
AND royaltyshare < .30
AND au_ord = 2;
14
Example as a Subquery
 SELECT au_lname,
au_fname
FROM authors
WHERE state = 'CA'
AND au_id IN
(SELECT au_id
FROM titleauthors
WHERE royaltyshare < .30
AND au_ord = 2);
15
Exercise - Use Subqueries
 List
the author's names for all books with
more than one author
16
Answer
 SELECT au_lname,
au_fname
FROM authors
WHERE au_id IN
(SELECT au_id
FROM titleauthors
WHERE title_id IN
(SELECT title_id
FROM titleauthors
WHERE au_ord > 1));
17
Using NOT IN
 SELECT pub_name
FROM publishers
WHERE pub_id NOT IN
(SELECT DISTINCT pub_id
FROM titles
WHERE type = 'business');
18
NOT IN Does Not Equal < >
 This
is NOT an equivalent statement…
– SELECT DISTINCT pub_name
FROM publishers p, titles t
WHERE p.pub_id = t.pub_id
AND type < > 'business';
 Why?
19
NOT not equal < >
 This
last statement returns any publisher
who is publishing a book that is not a
‘business’ type book. Every publisher has
at least one book that is some other type
than business, so all publishers are returned
by the statement.
20
Comparison Operator Subqueries
 Comparison
Operators (=, >, <, etc.)
 Must resolve to a single value… unless they
are modified with the ANY or ALL
keyword
21
Example
 SELECT au_lname,
au_fname
FROM authors
WHERE city =
(SELECT city
FROM publishers
WHERE pub_name = 'New Age Books');
22
Exercise
 List
the author’s name who appear as the
third author on a book. (Note: there's is
only one)
23
Answer
 SELECT au_lname,
au_fname
FROM authors
WHERE au_id =
(SELECT au_id
FROM titleauthors
WHERE au_ord = 3);
24
Using Aggregate Functions
 Aggregate
Functions always return a single
value for a set of rows
 SELECT title
FROM titles
WHERE advance/ytd_sales >
(SELECT MAX(price)
FROM titles);
25
GROUP BY and HAVING
 Don't
use GROUP or HAVING unless you
know that they will return a single value!
 SELECT title, type
FROM titles
WHERE price >
(SELECT MIN(price)
FROM titles
GROUP BY type
HAVING type = 'trad_cook');
26
Exercise
 List
the titles and advances where the
advance is equal to the average advance of
the popular computing books.
27
Answer
 SELECT title,
advance
FROM titles
WHERE advance =
(SELECT AVG(advance)
FROM titles
WHERE type = ‘popular_comp’);
28
Modified Comparison Operators
 You
may modify a comparison operator
with the ANY or ALL keyword
 Allows the Inner query to return more than
one value
29
Example
 SELECT au_lname
FROM authors
WHERE city > ALL
(SELECT city
FROM publishers);
30
ALL means All
 > ALL means
greater than all the values
returned from the Inner query
– SELECT price
FROM titles
WHERE price > ALL (1, 2, 3)
– Means where price is greater than 3.
 > ALL means
greater than the maximum
value
31
ANY means Some
 > ANY means
greater than at least one
value returned from the query
– SELECT price
FROM titles
WHERE price > ANY (1, 2, 3)
– Means where price is greater than 1.
 ANY mean
greater than the minimum value
32
Confusing SQL with English
 In
English:
– Which books commanded an advance greater
than any book published by Algodata
Infosystems?
 In
SQL:
– Which books have an advance greater than the
largest advance paid by Algodata Infosystems?
 Must
use the ALL keyword, not the ANY
33
Example
 SELECT au_lname
FROM authors
WHERE city > ANY
(SELECT city
FROM publishers);
34
Comparing IN, ANY and ALL
 The
'= ANY' operator is equivalent to IN
– SELECT au_lname, au_fname
FROM authors
WHERE city IN
(SELECT city FROM publishers);
– SELECT au_lname, au_fname
FROM authors
WHERE city = ANY
(SELECT city FROM publishers);
35
< > ANY is different than NOT IN
 SELECT DISTINCT au_lname,
au_fname
FROM authors
WHERE city < > ANY
(SELECT city
FROM publishers);
 What
does this find?
36
Discussion
 This
returns all authors because every
author does not in at least one of the citys
that a publishers is headquartered in.
37
Correctly Done
 SELECT au_lname,
au_fname
FROM authors
WHERE city NOT IN
(SELECT city
FROM publishers);
 Also,
the < > ALL would have worked
38
Exercise
 List
the sales order number, store id, and
sale date that have a sale date later than any
shipped date for books that cost $19.99.
39
Answer
 SELECT sonum,
stor_id, sdate
FROM sales, salesdetails
WHERE sdate > date_shipped
AND title_id IN
(SELECT DISTINCT title_id
FROM titles
WHERE price = 19.99);
40
Correlated Subqueries
 Inner
query references the outer query one
row at a time for each row in the Outer
query.
41
Example
 SELECT pub_name
FROM publishers p
WHERE 'business' IN
(SELECT type
FROM titles
WHERE pub_id = p.pub_id);
 Inner
query needs values from the Outer
query, then passes result to the Outer query
42
EXISTS Correlated Subquery
 EXISTS
tests for the presence or absence of
the "empty set" of rows.
 If Inner query returns at least one row…
– EXISTS will succeed
– NOT EXISTS will fail
 If
Inner query returns no row…
– EXISTS will fail
– NOT EXISTS will succeed
43
Example
 SELECT DISTINCT pub_name
FROM publishers p
WHERE EXISTS
(SELECT *
FROM titles
WHERE pub_id = p.pub_id
AND type = 'business');
44
Easier to use Join
 SELECT DISTINCT pub_name
FROM publishers p, titles t
WHERE t.pub_id = p.pub_id
AND type = 'business';
45
Example - Non-Existence
 SELECT title
FROM titles
WHERE NOT EXISTS
(SELECT title_id
FROM salesdetails
WHERE title_id = titles.title_id);
46
Intersection & Difference
 EXISTS
and NOT EXISTS can be used for
two set theory operation
– Intersection: Results are returned for the
elements that belong to both original sets
– Difference: Results are returned for the
elements that belong only to the first of the two
sets.
47
Example - Intersection
 SELECT DISTINCT city
FROM authors
WHERE EXISTS
(SELECT *
FROM publishers
WHERE authors.city = publishers.city);
– SELECT DISTINCT city FROM authors
WHERE city IN (SELECT city FROM publishers
WHERE city = authors.city);
48
Example - Difference
 SELECT DISTINCT city
FROM authors
WHERE NOT EXISTS
(SELECT *
FROM publishers
WHERE authors.city = publishers.city);
49
Subquery Rules
 The
select of an Inner query using an 'IN' or
a comparison operator can only have one
expression or column name
 Select list of an Inner query should be *
when using EXISTS
 Subqueries using unmodified operators
must return a single value
 Subqueries cannot use ORDER BY
50
Nesting More than Two
 SELECT au_lname,
au_fname
FROM authors
WHERE au_id IN
(SELECT au_id
FROM titleauthors
WHERE title_id IN
(SELECT title_id
FROM titles
WHERE type = 'popular_comp'));
51
Insert, Update, and Delete
 UPDATE
titles
SET price = price * 2
WHERE pub_id IN
(SELECT pub_id
FROM publishers
WHERE pub_name = 'New Age Books');
52
Copy from One Table to Another
 INSERT INTO
authors
(au_id, au_lname, au_fname)
SELECT ed_id, ed_lname, ed_fname
FROM editors
WHERE ed_lname LIKE 'S%';
53
Delete based on Data
 DELETE
FROM authors
WHERE au_lname IN
(SELECT ed_lname
FROM editors
WHERE ed_lname LIKE 'S%');
54
Last Slide - Chapter 8
 Assignment
#6 due next week
55