1. Trang chủ
  2. » Công Nghệ Thông Tin

SQL VISUAL QUICKSTART GUIDE- P28 pps

10 242 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 178,14 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

SELECT a1.au_fname, a1.au_lname, a2.au_fname, a2.au_lname FROM authors a1 INNER JOIN authors a2 ON a1.state = a2.state ORDER BY a1.au_id ASC, a2.au_id ASC; Listing au_fname au_lname au_f

Trang 1

For every biography, Listing 7.35 lists the

other biographies that outsold it Note that

the WHEREsearch condition requires type =

‘biography’for both tables t1andt2

because the join condition considers the

columntypeto be two separate columns

See Figure 7.35 for the result.

✔ Tip

■ Using WHEREsyntax, Listing 7.35 is

equiv-alent to:

SELECT t1.title_id, t1.sales,

t2.title_id AS “Better seller”,

t2.sales AS “Higher sales”

FROM titles t1, titles t2

WHERE t1.sales < t2.sales

AND t1.type = ‘biography’

AND t2.type = ‘biography’

ORDER BY t1.title_id ASC,

t2.sales ASC;

Chapter 7

Listing 7.35 For every biography, list the title ID and

sales of the other biographies that outsold it See Figure 7.35 for the result.

SELECT t1.title_id, t1.sales, t2.title_id AS "Better seller", t2.sales AS "Higher sales"

FROM titles t1 INNER JOIN titles t2

ON t1.sales < t2.sales

WHERE t1.type = 'biography' AND t2.type = 'biography' ORDER BY t1.title_id ASC, t2.sales ASC;

Listing

title_id sales Better seller Higher sales

- - -

-T06 11320 T12 100001

T06 11320 T07 1500200

T12 100001 T07 1500200

Figure 7.35 Result of Listing 7.35.

Trang 2

Listing 7.36 is a self-join to find all pairs

of authors within New York state See

Figure 7.36 for the result.

✔ Tip

■ Using WHEREsyntax, Listing 7.36 is equivalent to:

SELECT a1.au_fname, a1.au_lname, a2.au_fname, a2.au_lname FROM authors a1, authors a2 WHERE a1.state = a2.state AND a1.state = ‘NY’

ORDER BY a1.au_id ASC, a2.au_id ASC;

Listing 7.36 List all pairs of authors who live in New

York state See Figure 7.36 for the result.

SELECT

a1.au_fname, a1.au_lname,

a2.au_fname, a2.au_lname

FROM authors a1

INNER JOIN authors a2

ON a1.state = a2.state

ORDER BY a1.au_id ASC, a2.au_id ASC;

Listing

au_fname au_lname au_fname au_lname

- -

-Sarah Buchman -Sarah Buchman

Sarah Buchman Christian Kells

Christian Kells Sarah Buchman

Christian Kells Christian Kells

Figure 7.36 Result of Listing 7.36.

Trang 3

Figure 7.37 still isn’t quite what I want, because the two result rows are redundant The first row states that Sarah Buchman lives in the same state as Christian Kells, and the second row gives the same informa-tion To eliminate this redundancy, I’ll change the second join condition’s comparison

oper-ator from not-equal to less-than (Listing

7.38 and Figure 7.38).

✔ Tip

■ Using WHEREsyntax, Listing 7.38 is equiv-alent to:

SELECT a1.au_fname, a1.au_lname, a2.au_fname, a2.au_lname FROM authors a1, authors a2 WHERE a1.state = a2.state AND a1.au_id < a2.au_id AND a1.state = ‘NY’

ORDER BY a1.au_id ASC, a2.au_id ASC;

The first and fourth rows of Figure 7.36

are unnecessary because they indicate that

Sarah Buchman lives in the same state as Sarah

Buchman, and likewise for Christian Kells

Adding a join condition retains only those

rows in which the two authors differ

(Listing 7.37 and Figure 7.37).

✔ Tip

■ Using WHEREsyntax, Listing 7.37 is

equiv-alent to:

SELECT

a1.au_fname, a1.au_lname,

a2.au_fname, a2.au_lname

FROM authors a1, authors a2

WHERE a1.state = a2.state

AND a1.au_id <> a2.au_id

AND a1.state = ‘NY’

ORDER BY a1.au_id ASC,

a2.au_id ASC;

Chapter 7

Listing 7.37 List all different pairs of authors who live

in New York state See Figure 7.37 for the result.

SELECT

a1.au_fname, a1.au_lname,

a2.au_fname, a2.au_lname

FROM authors a1

INNER JOIN authors a2

ON a1.state = a2.state

AND a1.au_id <> a2.au_id

WHERE a1.state = 'NY'

Listing

Listing 7.38 List all different pairs of authors who

live in New York state, with no redundancies See Figure 7.38 for the result.

SELECT a1.au_fname, a1.au_lname, a2.au_fname, a2.au_lname FROM authors a1

INNER JOIN authors a2

ON a1.state = a2.state

Listing

Trang 4

To this point, I’ve used a single SELECT state-ment to retrieve data from one or more tables This chapter describes nested queries, which let you retrieve or modify data based on another query’s result

A subquery, or subselect, is a SELECT state-ment embedded in another SQL statestate-ment

You can nest a subquery in:

◆ TheSELECT,FROM,WHERE, or HAVINGclause

of a SELECTstatement

◆ Another subquery

◆ An INSERT,UPDATE, or DELETEstatement

In general, you can use a subquery anywhere

an expression is allowed, but your DBMS might restrict where they can appear This chapter covers subqueries nested in a SELECT

statement or another subquery; Chapter 10 covers subqueries embedded in INSERT,

UPDATE, and DELETEstatements

Subqueries

8

Trang 5

Subqueries

This section defines some terms and

intro-duces subqueries by giving an example of a

SELECTstatement that contains a simple

sub-query Subsequent sections explain the types

of subqueries and their syntax and semantics

Suppose that you want to list the names of

the publishers of biographies The naive

approach is to write two queries: one query

to retrieve the IDs of all the biography

pub-lishers (Listing 8.1 and Figure 8.1) and a

second query that uses the first query’s result

to list the publisher names (Listing 8.2 and

Figure 8.2).

A better way is to use an inner join

(Listing 8.3 and Figure 8.3); see “Creating

an Inner Join with INNER JOIN” in Chapter 7

Another alternative is to use a subquery

(Listing 8.4 and Figure 8.4) The subquery

in Listing 8.4 is shown in red A subquery

also is called an inner query, and the

state-ment containing a subquery is called an

outer query In other words, an enclosed

sub-query is an inner sub-query of an outer sub-query

Remember that a subquery can be nested

in another subquery, so inner and outer are

relative terms in statements with multiple

nested subqueries

Chapter 8

Listing 8.1 List the biography publishers See

Figure 8.1 for the result.

SELECT pub_id FROM titles WHERE type = 'biography';

Listing

pub_id

-P01 P03 P01 P01

Figure 8.1 Result of Listing 8.1 You can add DISTINCT

to the SELECT clause of Listing 8.1 to list the publishers only once; see “Eliminating Duplicate Rows with DISTINCT ” in Chapter 4.

Listing 8.2 This query uses the result of Listing 8.1

to list the names of the biography publishers See Figure 8.2 for the result.

SELECT pub_name FROM publishers

Listing

pub_name -Abatis Publishers Schadenfreude Press

Figure 8.2 Result of Listing 8.2.

Trang 6

I’ll explain how a DBMS executes subqueries

in “Simple and Correlated Subqueries” later

in this chapter, but for now, all that you need

to know is that in Listing 8.4, the DBMS processes the inner query (in red) first and then uses its interim result to run the outer query (in black) and get the final result The

INkeyword that introduces the subquery tests for list membership and works like IN

in “List Filtering with IN” in Chapter 4 Note that the inner query in Listing 8.4 is the same query as Listing 8.1, and the outer query is the same query as Listing 8.2

✔ Tips

Sometimes you’ll see the term subquery used to refer to an entire SQL statement

that contains one or more subqueries

To prevent confusion, I don’t use that terminology in this book

MySQL 4.1 and later support

subqueries, but earlier versions don’t You can’t run the examples in this chapter if you’re using MySQL 4.0 or earlier, but you have a few choices, in order of preference:

◆ Upgrade to the latest version of MySQL (www.mysql.com)

◆ Recast the subquery as a join (see

“Subqueries vs Joins” later in this chapter)

◆ Create a temporary table to hold the result of a subquery (see “Creating a Temporary Table with CREATE TEMPORARY TABLE” in Chapter 11 and the temporary-table example in the DBMS Tip in

“Creating Outer Joins with OUTER JOIN”

in Chapter 7, Listing 7.32)

◆ Simulate the subquery in a procedural host language such as PHP or Java (not covered in this book)

Listing 8.3 List the names of the biography publishers

by using an inner join See Figure 8.3 for the result.

SELECT DISTINCT pub_name

FROM publishers p

INNER JOIN titles t

ON p.pub_id = t.pub_id

WHERE t.type = 'biography';

Listing

pub_name

-Abatis Publishers

Schadenfreude Press

Figure 8.3 Result of Listing 8.3.

Listing 8.4 List the names of the biography publishers

by using a subquery See Figure 8.4 for the result.

SELECT pub_name

FROM publishers

WHERE pub_id IN

( SELECT pub_id

FROM titles

WHERE type = 'biography' );

Listing

pub_name

-Abatis Publishers

Schadenfreude Press

Figure 8.4 Result of Listing 8.4.

Trang 7

Subquery Syntax

The syntax of a subquery is the same as

that of a normal SELECTstatement (see

Chapters 4 through 7) except for the

follow-ing differences:

◆ You can nest a subquery in a SELECT,

FROM,WHERE, or HAVINGclause or in

another subquery

◆ Always enclose a subquery in parentheses

◆ Don’t terminate a subquery with a

semi-colon (You still must terminate the

statement that contains the subquery

with a semicolon.)

◆ Don’t put an ORDER BYclause in a subquery

(A subquery returns an intermediate result

that you never see, so sorting a subquery

makes no sense.)

◆ A subquery is a single SELECTstatement

(You can’t use, say, a UNIONof multiple

SELECTstatements as a subquery.)

◆ A subquery can use columns in the

tables listed in its own FROMclause or in

the outer query’s FROMclause

◆ If a table appears in an inner query but

not in the outer query, you can’t include

that table’s columns in the final result

(that is, in the outer query’s SELECTclause)

◆ Depending on the context in which it’s

used, a subquery might be required to

return a limited number of rows or

columns The SQL standard categorizes

In practice, a subquery usually appears in a

WHEREclause that takes one of these forms:

◆ WHERE test_expr op (subquery)

◆ WHERE test_expr [NOT] IN (subquery)

◆ WHERE test_expr op ALL (subquery)

◆ WHERE test_expr op ANY (subquery)

◆ WHERE [NOT] EXISTS (subquery)

test_expr is a literal value, a column name,

an expression, or a scalar subquery; op is a

comparison operator (=,<>,<,<=,>, or >=);

and subquery is a simple or correlated

sub-query I’ll cover each of these forms later in this chapter You can use these subquery forms in a HAVINGclause, too

✔ Tip

■ The SQL standard doesn’t

specify a maximum number

of subquery nesting levels, so your DBMS will set its own upper limit This built-in limit typically exceeds the limit of human comprehension

Microsoft SQL Server, for example,

allows 32 levels of nesting

Chapter 8

Table 8.1

Size of Subquery Results

Trang 8

Subqueries vs Joins

In “Understanding Subqueries” earlier in

this chapter, Listings 8.3 and 8.4 showed two equivalent queries: one used a join, and the

other used a subquery Many subqueries can

be formulated alternatively as joins In fact,

a subquery is a way to relate one table to

another without actually doing a join

Because subqueries can be hard to use and

debug, you might prefer to use joins, but you can pose some questions only as subqueries

In cases where you can use subqueries and

joins interchangeably, you should test queries

on your DBMS to see whether a

perform-ance difference exists between a statement

that uses a subquery and a semantically

equivalent version that uses a join For

example, the query

SELECT MAX(table1.col1)

FROM table1

WHERE table1.col1 IN

(SELECT table2.col1

FROM table2);

usually will run faster than

SELECT MAX(table1.col1)

FROM table1

INNER JOIN table2

ON table1.col1 = table2.col1;

For more information, see “Comparing

Equivalent Queries” later in this chapter

Trang 9

The following syntax diagrams show some

equivalent statements that use subqueries

and joins These two statements are

equiva-lent (INsubquery):

SELECT *

FROM table1

WHERE id IN

(SELECT id FROM table2);

and (inner join):

SELECT DISTINCT table1.*

FROM table1

INNER JOIN table2

ON table1.id = table2.id;

See Listings 8.5a and 8.5b and Figure 8.5

for an example

Chapter 8

Listing 8.5a This statement uses a subquery to list

the authors who live in the same city in which a publisher is located See Figure 8.5 for the result.

SELECT au_id, city FROM authors WHERE city IN ( SELECT city FROM publishers );

Listing

Listing 8.5b This statement is equivalent to

Listing 8.5a but uses an inner join instead of a subquery See Figure 8.5 for the result.

SELECT DISTINCT a.au_id, a.city FROM authors a

INNER JOIN publishers p

ON a.city = p.city;

Listing

au_id city - -A03 San Francisco A04 San Francisco A05 New York

Figure 8.5 Result of Listings 8.5a and 8.5b.

Trang 10

These three statements are equivalent (NOT INsubquery):

SELECT *

FROM table1 WHERE id NOT IN (SELECT id FROM table2);

and (NOT EXISTSsubquery):

SELECT *

FROM table1

WHERE NOT EXISTS (SELECT *

FROM table2 WHERE table1.id = table2.id);

and (left outer join):

SELECT table1.*

FROM table1 LEFT OUTER JOIN table2

ON table1.id = table2.id WHERE table2.id IS NULL;

See Listings 8.6a, 8.6b, and 8.6c and

Figure 8.6 for an example INandEXISTS

subqueries are covered later in this chapter

Listing 8.6a This statement uses an IN subquery to

list the authors who haven’t written (or cowritten) a

book See Figure 8.6 for the result.

SELECT au_id, au_fname, au_lname

FROM authors

(SELECT au_id FROM title_authors);

Listing

Listing 8.6b This statement is equivalent to

Listing 8.6a but uses an EXISTS subquery instead

of an IN subquery See Figure 8.6 for the result.

SELECT au_id, au_fname, au_lname

FROM authors a

(SELECT *

FROM title_authors ta

WHERE a.au_id = ta.au_id);

Listing

Listing 8.6c This statement is equivalent to

Listings 8.6a and 8.6b but uses a left outer join

instead of a subquery See Figure 8.6 for the result.

SELECT a.au_id, a.au_fname, a.au_lname

FROM authors a

LEFT OUTER JOIN title_authors ta

ON a.au_id = ta.au_id

WHERE ta.au_id IS NULL;

Listing

au_id au_fname au_lname

- -

-A07 Paddy O'Furniture

Figure 8.6 Result of Listings 8.6a, 8.6b, and 8.6c.

Ngày đăng: 05/07/2014, 05:20

TỪ KHÓA LIÊN QUAN