✔ Tip ■ Using WHERE syntax, Listing 7.7 is equiva-lent to: SELECT a.au_id, a.au_fname, a.au_lname, ta.title_id FROM authors a, title_authors ta WHERE a.au_id = ta.au_id ORDER BY a.au_id
Trang 1Creating an Inner Join
An inner join:
◆ Uses a comparison operator ( = , <> , < , <= ,
> , or >= ) to match rows from two tables
based on the values in common columns
from each table You can retrieve all rows
in which the author identifier (the column
au_id ) is the same in both the tables
authors and title_authors , for example.
◆ Returns a result that contains only joined
rows that satisfy the join condition(s).
◆ Is the most common type of join.
To create an inner join:
◆ Type:
SELECT columns
FROM table1
INNER JOIN table2
ON join_conditions
columns is one or more comma-separated
expressions or column names from table1
or table2 table1 and table2 are the names
of the joined tables If the tables have
some column names in common, qualify
those column names with the names of
the tables.
join_conditions specifies one or more
join conditions to be evaluated for each
pair of joined rows A join condition
takes this form:
[table1.]column op [table2.]column
op usually is = but can be any compari-son operator: = , <> , < , <= , > , or >= (refer
to Table 4.2 in Chapter 4) You can com-bine multiple join conditions with AND
or OR ; see “Combining and Negating Conditions with AND, OR, and NOT ” in Chapter 4.
✔ Tips
■ To create an inner join of three or more tables by using JOIN syntax, type:
SELECT columns FROM table1 INNER JOIN table2
ON join_condition1 INNER JOIN table3
ON join_condition2
Using WHERE syntax, type:
SELECT columns FROM table1, table2,
WHERE join_condition1 AND join_condition2
■ If you’re using WHERE syntax and you omit a join condition accidentally, you’ll create a cross join If the affected tables are large production tables, you’ll have a
“runaway query” that you might have to ask your database administrator to kill.
■ By default, JOIN (without CROSS , NATURAL , OUTER , or any other modifiers) is equiva-lent to INNER JOIN
Trang 2■ You can use WHERE syntax or
JOIN syntax in Microsoft
joins that involve three or more tables, Access requires you to nest joins by using the following general syntax:
SELECT columns FROM table1 INNER JOIN (table2 INNER JOIN (table3 INNER JOIN (table4
INNER JOIN )
ON table3.column3 op table4.column4)
ON table2.column2 op table3.column3)
ON table1.column1 op table2.column2;
(Other DBMSs also let you nest joins by using parentheses, but Access requires it.)
use WHERE joins instead Oracle 9i and
later support JOIN syntax.
Listing 7.7 joins two tables on the column
au_id to list the books that each author wrote (or cowrote) Each author’s au_id in the table authors matches zero or more rows
in the table title_authors See Figure 7.7
for the result Note that author A07 (Paddy O’Furniture) is omitted from the result because he has written no books and so has
no matching rows in title_authors
✔ Tip
■ Using WHERE syntax, Listing 7.7 is equiva-lent to:
SELECT a.au_id, a.au_fname, a.au_lname, ta.title_id FROM authors a, title_authors ta WHERE a.au_id = ta.au_id
ORDER BY a.au_id ASC, ta.title_id ASC;
Listing 7.7 List the books that each author wrote (or
cowrote) See Figure 7.7 for the result.
SELECT
a.au_id,
a.au_fname,
a.au_lname,
ta.title_id
FROM authors a
INNER JOIN title_authors ta
ON a.au_id = ta.au_id
ORDER BY a.au_id ASC, ta.title_id ASC;
Listing
au_id au_fname au_lname title_id
- - -
-A01 Sarah Buchman T01
A01 Sarah Buchman T02
A01 Sarah Buchman T13
A02 Wendy Heydemark T06
A02 Wendy Heydemark T07
A02 Wendy Heydemark T10
A02 Wendy Heydemark T12
A03 Hallie Hull T04
A03 Hallie Hull T11
A04 Klee Hull T04
A04 Klee Hull T05
A04 Klee Hull T07
A04 Klee Hull T11
A05 Christian Kells T03
A06 Kellsey T08
A06 Kellsey T09
A06 Kellsey T11
Figure 7.7 Result of Listing 7.7.
Trang 3Listing 7.8 joins two tables on the column
pub_id to list each book’s title name and ID,
and each book’s publisher name and ID.
Note that the join is necessary to retrieve
only the publisher name (the fourth column
in the result); all the other three columns are
available in the table titles See Figure 7.8
for the result.
✔ Tip
■ Using WHERE syntax, Listing 7.8 is
equiva-lent to:
SELECT t.title_id, t.title_name,
t.pub_id, p.pub_name
FROM titles t, publishers p
WHERE p.pub_id = t.pub_id
ORDER BY t.title_name ASC;
Listing 7.8 List each book’s title name and ID and
each book’s publisher name and ID See Figure 7.8 for the result.
SELECT t.title_id, t.title_name, t.pub_id, p.pub_name
FROM titles t INNER JOIN publishers p
ON p.pub_id = t.pub_id
ORDER BY t.title_name ASC;
Listing
title_id title_name pub_id pub_name
- - -
-T01 1977! P01 Abatis Publishers
T02 200 Years of German Humor P03 Schadenfreude Press
T03 Ask Your System Administrator P02 Core Dump Books
T04 But I Did It Unconsciously P04 Tenterhooks Press
T05 Exchange of Platitudes P04 Tenterhooks Press
T06 How About Never? P01 Abatis Publishers
T07 I Blame My Mother P03 Schadenfreude Press
T08 Just Wait Until After School P04 Tenterhooks Press
T09 Kiss My Boo-Boo P04 Tenterhooks Press
T10 Not Without My Faberge Egg P01 Abatis Publishers
T11 Perhaps It's a Glandular Problem P04 Tenterhooks Press
T12 Spontaneous, Not Annoying P01 Abatis Publishers
T13 What Are The Civilian Applications? P03 Schadenfreude Press
Trang 4Listing 7.9 uses two join conditions to list
the authors who live in the same city and state as some publisher (any publisher) See
Figure 7.9 for the result Note that this
query is a natural join on the identically named, nonkey columns city and state in the two tables (see “Creating a Natural Join with NATURAL JOIN ” earlier in this chapter).
An equivalent query is:
SELECT a.au_id, a.au_fname, a.au_lname, a.city, a.state FROM authors a
NATURAL JOIN publishers p ORDER BY a.au_id ASC;
✔ Tip
■ Using WHERE syntax, Listing 7.9 is equiva-lent to:
SELECT a.au_id, a.au_fname, a.au_lname, a.city, a.state FROM authors a, publishers p WHERE a.city = p.city AND a.state = p.state ORDER BY a.au_id ASC;
Listing 7.9 List the authors who live in the same
city and state in which a publisher is located See
Figure 7.9 for the result.
SELECT
a.au_id,
a.au_fname,
a.au_lname,
a.city,
a.state
FROM authors a
INNER JOIN publishers p
ON a.city = p.city
AND a.state = p.state
ORDER BY a.au_id;
Listing
au_id au_fname au_lname city state
- -
-A03 Hallie Hull San Francisco CA
A04 Klee Hull San Francisco CA
A05 Christian Kells New York NY
Figure 7.9 Result of Listing 7.9.
Trang 5Listing 7.10 combines an inner join with
WHERE conditions to list books published in
California or outside the large North American
countries; see “Filtering Rows with WHERE ” in
Chapter 4 See Figure 7.10 for the result.
✔ Tip
■ Using WHERE syntax, Listing 7.10 is
equiv-alent to:
SELECT t.title_id, t.title_name,
p.state, p.country
FROM titles t, publishers p
WHERE t.pub_id = p.pub_id
AND (p.state = ‘CA’
OR p.country NOT IN
(‘USA’, ‘Canada’, ‘Mexico’)) ORDER BY t.title_id ASC;
Listing 7.10 List the books published in California or
outside the large North American countries See Figure 7.10 for the result.
SELECT t.title_id, t.title_name, p.state, p.country
FROM titles t INNER JOIN publishers p
ON t.pub_id = p.pub_id
WHERE p.state = 'CA'
OR p.country NOT IN ('USA', 'Canada', 'Mexico')
ORDER BY t.title_id ASC;
Listing
title_id title_name state country
- -
-T02 200 Years of German Humor NULL Germany
T03 Ask Your System Administrator CA USA
T04 But I Did It Unconsciously CA USA
T05 Exchange of Platitudes CA USA
T07 I Blame My Mother NULL Germany
T08 Just Wait Until After School CA USA
T09 Kiss My Boo-Boo CA USA
T11 Perhaps It's a Glandular Problem CA USA
T13 What Are The Civilian Applications? NULL Germany
Trang 6Listing 7.11 combines an inner join with
the aggregate function COUNT() and a GROUP
BY clause to list the number of books that each author wrote (or cowrote) For infor-mation about aggregate functions and GROUP
BY , see Chapter 6 See Figure 7.11 for the
result Note that, as in Figure 7.7, author A07 (Paddy O’Furniture) is omitted from the result because he has written no books and
so has no matching rows in title_authors See Listing 7.30 in “Creating Outer Joins with OUTER JOIN ” later in this chapter for an example that lists authors who have written
no books.
✔ Tip
■ Using WHERE syntax, Listing 7.11 is equiv-alent to:
SELECT a.au_id, COUNT(ta.title_id)
AS “Num books”
FROM authors a, title_authors ta WHERE a.au_id = ta.au_id
GROUP BY a.au_id ORDER BY a.au_id ASC;
Listing 7.11 List the number of books that each author
wrote (or cowrote) See Figure 7.11 for the result.
SELECT
a.au_id,
COUNT(ta.title_id) AS "Num books"
FROM authors a
INNER JOIN title_authors ta
ON a.au_id = ta.au_id
GROUP BY a.au_id
ORDER BY a.au_id ASC;
Listing
au_id Num books
-
-A01 3
A02 4
A03 2
A04 4
A05 1
A06 3
Figure 7.11 Result of Listing 7.11.
Trang 7Listing 7.12 uses WHERE conditions to list
the advance paid for each biography See
Figure 7.12 for the result.
✔ Tip
■ Using WHERE syntax, Listing 7.12 is
equiv-alent to:
SELECT t.title_id, t.title_name,
r.advance
FROM royalties r, titles t
WHERE r.title_id = t.title_id
AND t.type = ‘biography’
AND r.advance IS NOT NULL
ORDER BY r.advance DESC;
Listing 7.12 List the advance paid for each biography.
See Figure 7.12 for the result.
SELECT t.title_id, t.title_name, r.advance
FROM royalties r INNER JOIN titles t
ON r.title_id = t.title_id
WHERE t.type = 'biography' AND r.advance IS NOT NULL ORDER BY r.advance DESC;
Listing
title_id title_name advance - - -T07 I Blame My Mother 1000000.00 T12 Spontaneous, Not Annoying 50000.00 T06 How About Never? 20000.00
Figure 7.12 Result of Listing 7.12.
Trang 8Listing 7.13 uses aggregate functions and a
GROUP BY clause to list the count and total advance paid for each type of book See
Figure 7.13 for the result.
✔ Tip
■ Using WHERE syntax, Listing 7.13 is equiv-alent to:
SELECT t.type, COUNT(r.advance)
AS “COUNT(r.advance)”, SUM(r.advance)
AS “SUM(r.advance)”
FROM royalties r, titles t WHERE r.title_id = t.title_id AND r.advance IS NOT NULL GROUP BY t.type
ORDER BY t.type ASC;
Listing 7.13 List the count and total advance paid for
each type of book See Figure 7.13 for the result.
SELECT
t.type,
COUNT(r.advance)
AS "COUNT(r.advance)",
SUM(r.advance)
AS "SUM(r.advance)"
FROM royalties r
INNER JOIN titles t
ON r.title_id = t.title_id
WHERE r.advance IS NOT NULL
GROUP BY t.type
ORDER BY t.type ASC;
Listing
type COUNT(r.advance) SUM(r.advance)
-
-biography 3 1070000.00
children 2 0.00
computer 1 15000.00
history 3 31000.00
psychology 3 220000.00
Figure 7.13 Result of Listing 7.13.
Trang 9Listing 7.14 is similar to Listing 7.13,
except that it uses an additional grouping
column to list the count and total advance
paid for each type of book by publisher See
Figure 7.14 for the result.
✔ Tip
■ Using WHERE syntax, Listing 7.14 is
equiv-alent to:
SELECT t.type, t.pub_id,
COUNT(r.advance)
AS “COUNT(r.advance)”, SUM(r.advance)
AS “SUM(r.advance)”
FROM royalties r, titles t
WHERE r.title_id = t.title_id
AND r.advance IS NOT NULL
GROUP BY t.type, t.pub_id
ORDER BY t.type ASC, t.pub_id ASC;
Listing 7.14 List the count and total advance paid for
each type of book, by publisher See Figure 7.14 for the result.
SELECT t.type, t.pub_id, COUNT(r.advance) AS "COUNT(r.advance)", SUM(r.advance) AS "SUM(r.advance)"
FROM royalties r INNER JOIN titles t
ON r.title_id = t.title_id
WHERE r.advance IS NOT NULL GROUP BY t.type, t.pub_id ORDER BY t.type ASC, t.pub_id ASC;
Listing
type pub_id COUNT(r.advance) SUM(r.advance)
- -
-biography P01 2 70000.00
biography P03 1 1000000.00
children P04 2 0.00
computer P02 1 15000.00
history P01 1 10000.00
history P03 2 21000.00
psychology P04 3 220000.00
Trang 10Listing 7.15 uses a HAVING clause to list the number of coauthors of each book written
by two or more authors For information about HAVING , see “Filtering Groups with HAVING ” in Chapter 6 See Figure 7.15 for
the result.
✔ Tip
■ Using WHERE syntax, Listing 7.15 is equiv-alent to:
SELECT ta.title_id, COUNT(ta.au_id) AS “Num authors”
FROM authors a, title_authors ta WHERE a.au_id = ta.au_id
GROUP BY ta.title_id HAVING COUNT(ta.au_id) > 1 ORDER BY ta.title_id ASC;
Listing 7.15 List the number of coauthors of each
book written by two or more authors See Figure 7.15
for the result.
SELECT
ta.title_id,
COUNT(ta.au_id) AS "Num authors"
FROM authors a
INNER JOIN title_authors ta
ON a.au_id = ta.au_id
GROUP BY ta.title_id
HAVING COUNT(ta.au_id) > 1
ORDER BY ta.title_id ASC;
Listing
title_id Num authors
-
-T04 2
T07 2
T11 3
Figure 7.15 Result of Listing 7.15.