Tải bản đầy đủ (.pdf) (10 trang)

SQL VISUAL QUICKSTART GUIDE- P45 ppsx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (176.79 KB, 10 trang )

Listing 15.13 is a variation of Listing 15.12
that finds all regions of length 2. See
Figure 15.13 for the result. Note that over-
lapping subregions are listed. To return
regions of length n, change the
WHERE
clause’s second condition to:
AND t2.id - t1.id = n - 1
420
Chapter 15
Finding Sequences, Runs, and Regions
Listing 15.13 List all regions of length 2. See
Figure 15.13 for the result.
SELECT
t1.id AS StartReg,
t2.id AS EndReg,
t2.id - t1.id + 1 AS RegLen
FROM temps t1, temps t2
WHERE (t1.id < t2.id)
AND t2.id - t1.id = 1
AND NOT EXISTS(
SELECT *
FROM temps t3
WHERE (t3.hi_temp <> 50
AND t3.id BETWEEN
t1.id AND t2.id)
);
Listing
StartReg EndReg RegLen

4 5 2


5 6 2
10 11 2
Figure 15.13 Result of Listing 15.13.
Limiting the Number of
Rows Returned
In practice it’s common to use queries that
return a certain number (n) of rows that fall
at the top or the bottom of a range specified
by an
ORDER BY
clause. SQL doesn’t require
an
ORDER BY
clause, but if you omit it, the
query will return an arbitrary set of rows
(because SQL doesn’t promise to deliver query
results in any particular order without an
ORDER BY
clause).
The examples in this section use the table
empsales
(Listing 15.14 and Figure 15.14),
which lists sales figures by employee. Note
that some employees have the same sales
amounts. A correct query for the top three
salespeople in
empsales
actually will return
four rows: employees E09, E02, E10, and E05.
Ties shouldn’t force the query to choose

arbitrarily between equal values (E10 and
E05 in this case). No standard terminology
exists, but queries that return at most n rows
(regardless of ties) sometimes are called
limit queries. Queries that include ties and
return possibly more than n rows are top-n
queries or quota queries.
The SQL:2003 standard introduced
the functions
ROW_NUMBER()
and
RANK()
to use in limit and top-n queries.
Microsoft SQL Server 2005 and later,
Oracle, and DB2 support both functions.
Queries that use pre-2003 SQL are complex,
unintuitive, and run slowly (see the Tips at
the end of this section for an SQL-92 exam-
ple). The SQL standard has lagged DBMSs,
which for years have offered nonstandard
extensions to create these types of queries.
Some DBMSs also let you return a percent-
age of rows (rather than a fixed n) or return
offsets by skipping a specified number of
initial rows (returning rows 3–8 instead of
1–5, for example). This section covers the
DBMS extensions individually.
421
SQL Tricks
Limiting the Number of Rows Returned

Listing 15.14 List employees by descending sales. See
Figure 15.14 for the result.
SELECT emp_id, sales
FROM empsales
ORDER BY sales DESC;
Listing
emp_id sales

E09 900
E02 800
E10 700
E05 700
E01 600
E04 500
E03 500
E06 500
E08 400
E07 300
Figure 15.14 Result of Listing 15.14.
✔ Tips

You also can use these queries to limit
the number of rows affected by an
UPDATE
or
DELETE
(see Chapter 10).

Some of these queries might be illegal in
some contexts (such as in subqueries or

views); see your DBMS documentation.

Some of the following examples are based
on the ideas in Troels Arvin’s “Comparison
of Different SQL Implementations”
(
/>).
Microsoft Access
Listing 15.15 lists the top three salespeo-
ple, including ties. See Figure 15.15 for the
result. This query orders highest to lowest;
to reverse the order, change
DESC
to
ASC
in
the
ORDER BY
clause.
Listing 15.16 lists the bottom 40 percent of
salespeople, including ties. See Figure 15.16
for the result. This query orders lowest to
highest; to reverse the order, change
ASC
to
DESC
in the
ORDER BY
clause.
The

TOP
clause always includes ties. Its
syntax is:
TOP n [PERCENT]
✔ Tip

The following offset query returns n rows
but excludes the topmost skip rows from
the result. This query orders highest to
lowest; to reverse the order, change
ASC
to
DESC
and
DESC
to
ASC
in each
ORDER BY
clause.
SELECT *
FROM (
SELECT TOP n *
FROM (
SELECT TOP n + skip *
FROM table
ORDER BY sort_col DESC)
ORDER BY sort_col ASC)
ORDER BY sort_col DESC;
422

Chapter 15
Limiting the Number of Rows Returned
Listing 15.15 List the top three salespeople, with ties.
See Figure 15.15 for the result.
SELECT TOP 3 emp_id, sales
FROM empsales
ORDER BY sales DESC;
Listing
emp_id sales

E09 900
E02 800
E10 700
E05 700
Figure 15.15 Result of Listing 15.15.
Listing 15.16 List the bottom 40 percent of
salespeople, with ties. See Figure 15.16 for the result.
SELECT TOP 40 PERCENT emp_id, sales
FROM empsales
ORDER BY sales ASC;
Listing
emp_id sales

E07 300
E08 400
E06 500
E04 500
E03 500
Figure 15.16 Result of Listing 15.16.
Microsoft SQL Server

Listing 15.17 lists the top three salespeo-
ple, not including ties. See Figure 15.17 for
the result. Note that this query is inconsis-
tent when ties exist; rerunning it can return
either E10 or E05, depending on how
ORDER
BY
sorts the table. This query orders highest
to lowest; to reverse the order, change
DESC
to
ASC
in the
ORDER BY
clause.
Listing 15.18 lists the top three salespeo-
ple, including ties. See Figure 15.18 for the
result. This query orders highest to lowest;
to reverse the order, change
DESC
to
ASC
in
the
ORDER BY
clause.
423
SQL Tricks
Limiting the Number of Rows Returned
Listing 15.17 List the top three salespeople, without

ties. See Figure 15.17 for the result.
SELECT TOP 3 emp_id, sales
FROM empsales
ORDER BY sales DESC;
Listing
emp_id sales

E09 900
E02 800
E05 700
Figure 15.17 Result of Listing 15.17.
Listing 15.18 List the top three salespeople, with ties.
See Figure 15.18 for the result.
SELECT TOP 3 WITH TIES emp_id, sales
FROM empsales
ORDER BY sales DESC;
Listing
emp_id sales

E09 900
E02 800
E05 700
E10 700
Figure 15.18 Result of Listing 15.18.
Listing 15.19 lists the bottom 40 percent of
salespeople, including ties. See Figure 15.19
for the result. This query orders lowest to
highest; to reverse the order, change
ASC
to

DESC
in the
ORDER BY
clause.
The
TOP
clause’s syntax is:
TOP n [PERCENT] [WITH TIES]
✔ Tips

The statement
SET ROWCOUNT n
provides
an alternative method returning n rows.

To retrieve a specific subset of ordered
rows, you can use a cursor (not covered
in this book). The following offset query
returns n rows but excludes the topmost
skip rows from the result. This query
orders highest to lowest; to reverse the
order, change
ASC
to
DESC
and
DESC
to
ASC
in each

ORDER BY
clause.
SELECT *
FROM (
SELECT TOP n *
FROM (
SELECT TOP n + skip *
FROM table
ORDER BY sort_col DESC)
AS any_name1
ORDER BY sort_col ASC)
AS any_name2
ORDER BY sort_col DESC;
424
Chapter 15
Limiting the Number of Rows Returned
Listing 15.19 List the bottom 40 percent of sales-
people, with ties. See Figure 15.19 for the result.
SELECT TOP 40 PERCENT WITH TIES
emp_id, sales
FROM empsales
ORDER BY sales ASC;
Listing
emp_id sales

E07 300
E08 400
E06 500
E03 500
E04 500

Figure 15.19 Result of Listing 15.19.
Oracle
Use the built-in
ROWNUM
pseudocolumn to
limit the number or rows returned. The first
row selected has a
ROWNUM
of 1, the second
has 2, and so on. Use the window function
RANK()
to include ties.
Listing 15.20 lists the top three salespeo-
ple, not including ties. See Figure 15.20 for
the result. Note that this query is inconsis-
tent when ties exist; re-running it can return
either E10 or E05, depending on how
ORDER
BY
sorts the table. This query orders highest
to lowest; to reverse the order, change
DESC
to
ASC
in the
ORDER BY
clause.
Listing 15.21 lists the top three salespeo-
ple, including ties. See Figure 15.21 for the
result. This query orders highest to lowest;

to reverse the order, change
DESC
to
ASC
in
the
ORDER BY
clause.
✔ Tips

The function
ROW_NUMBER()
provides an
alternative method of assigning unique
numbers to rows.

To retrieve a specific subset of ordered
rows, you can use a cursor (not covered
in this book). The following offset query
returns n rows but excludes the topmost
skip rows from the result. This query orders
highest to lowest; to reverse the order,
change
DESC
to
ASC
in the
ORDER BY
clause.
SELECT *

FROM (
SELECT
ROW_NUMBER() OVER
(ORDER BY sort_col DESC)
AS rnum,
columns
FROM table)
WHERE rnum > skip
AND rnum <= (n + skip);
425
SQL Tricks
Limiting the Number of Rows Returned
Listing 15.20 List the top three salespeople, without
ties. See Figure 15.20 for the result.
SELECT emp_id, sales
FROM (
SELECT *
FROM empsales
ORDER BY sales DESC)
WHERE ROWNUM <= 3;
Listing
emp_id sales

E09 900
E02 800
E05 700
Figure 15.20 Result of Listing 15.20.
Listing 15.21 List the top three salespeople, with ties.
See Figure 15.21 for the result.
SELECT emp_id, sales

FROM (
SELECT
RANK() OVER
(ORDER BY sales DESC)
AS sales_rank,
emp_id,
sales
FROM empsales)
WHERE sales_rank <= 3;
Listing
emp_id sales

E09 900
E02 800
E05 700
E10 700
Figure 15.21 Result of Listing 15.21.
IBM DB2
Listing 15.22 lists the top three salespeo-
ple, not including ties. See Figure 15.22 for
the result. Note that this query is inconsis-
tent when ties exist; re-running it can return
either E10 or E05, depending on how
ORDER
BY
sorts the table. This query orders highest
to lowest; to reverse the order, change
DESC
to
ASC

in the
ORDER BY
clause.
Listing 15.23 lists the top three salespeo-
ple, including ties. See Figure 15.23 for the
result. This query orders highest to lowest; to
reverse the order, change
DESC
to
ASC
in the
ORDER BY
clause.
The
FETCH
clause’s syntax is:
FETCH FIRST n ROW[S] ONLY
✔ Tip

To retrieve a specific subset of ordered
rows, you can use a cursor (not covered
in this book). The following offset query
returns n rows but excludes the topmost
skip rows from the result. This query
orders highest to lowest; to reverse the
order, change
DESC
to
ASC
in the

ORDER BY
clause.
SELECT *
FROM (
SELECT
ROW_NUMBER() OVER
(ORDER BY sort_col DESC)
AS rnum,
columns
FROM table)
AS any_name
WHERE rnum > skip
AND rnum <= n + skip;
426
Chapter 15
Limiting the Number of Rows Returned
Listing 15.22 List the top three salespeople, without
ties. See Figure 15.22 for the result.
SELECT emp_id, sales
FROM empsales
ORDER BY sales DESC
FETCH FIRST 3 ROWS ONLY;
Listing
emp_id sales

E09 900
E02 800
E05 700
Figure 15.22 Result of Listing 15.22.
Listing 15.23 List the top three salespeople, with ties.

See Figure 15.23 for the result.
SELECT emp_id, sales
FROM (
SELECT
RANK() OVER
(ORDER BY sales DESC)
AS sales_rank,
emp_id,
sales
FROM empsales)
AS any_name
WHERE sales_rank <= 3;
Listing
emp_id sales

E09 900
E02 800
E05 700
E10 700
Figure 15.23 Result of Listing 15.23.
MySQL
Listing 15.24 lists the top three salespeo-
ple, not including ties. See Figure 15.24 for
the result. Note that this query is inconsis-
tent when ties exist; re-running it can return
either E10 or E05, depending on how
ORDER
BY
sorts the table. This query orders highest
to lowest; to reverse the order, change

DESC
to
ASC
in the
ORDER BY
clause.
Listing 15.25 lists the top three salespeople,
including ties. The
OFFSET
value is n – 1 = 2.
COALESCE()
’s second argument lets the query
work in case the table has fewer than n rows;
see “Checking for Nulls with
COALESCE()
” in
Chapter 5. See Figure 15.25 for the result.
This query orders highest to lowest; to
reverse the order, change
>=
to
<=
in the
comparison, change
MIN()
to
MAX()
in the
second subquery, and change
DESC

to
ASC
in each
ORDER BY
clause.
427
SQL Tricks
Limiting the Number of Rows Returned
Listing 15.24 List the top three salespeople, without
ties. See Figure 15.24 for the result.
SELECT emp_id, sales
FROM empsales
ORDER BY sales DESC
LIMIT 3;
Listing
emp_id sales

E09 900
E02 800
E10 700
Figure 15.24 Result of Listing 15.24.
Listing 15.25 List the top three salespeople, with ties.
See Figure 15.25 for the result.
SELECT emp_id, sales
FROM empsales
WHERE sales >= COALESCE(
(SELECT sales
FROM empsales
ORDER BY sales DESC
LIMIT 1 OFFSET 2),

(SELECT MIN(sales)
FROM empsales))
ORDER BY sales DESC;
Listing
emp_id sales

E09 900
E02 800
E05 700
E10 700
Figure 15.25 Result of Listing 15.25.
Listing 15.26 lists the top three sales-
people, skipping the initial four rows. See
Figure 15.26 for the result. Note that this
query is inconsistent when ties exist.
This query orders highest to lowest; to
reverse the order, change
DESC
to
ASC
in
the
ORDER BY
clause.
The
LIMIT
clause’s syntax is:
LIMIT n [OFFSET skip]
or
LIMIT [skip,] n

The offset of the initial row is 0 (not 1).
PostgreSQL
Listing 15.27 lists the top three salespeo-
ple, not including ties. See Figure 15.27 for
the result. Note that this query is inconsis-
tent when ties exist; re-running it can return
either E10 or E05, depending on how
ORDER
BY
sorts the table. This query orders highest
to lowest; to reverse the order, change
DESC
to
ASC
in the
ORDER BY
clause.
Listing 15.28 lists the top three salespeople,
including ties. The
OFFSET
value is n – 1 = 2.
See Figure 15.28 for the result. This query
orders highest to lowest; to reverse the order,
change
>=
to
<=
in the comparison and
change
DESC

to
ASC
in each
ORDER BY
clause.
Listing 15.29 lists the top three sales-
people, skipping the initial four rows. See
Figure 15.29 for the result. Note that this
query is inconsistent when ties exist.
This query orders highest to lowest; to
reverse the order, change
DESC
to
ASC
in
the
ORDER BY
clause.
The
LIMIT
clause’s syntax is:
LIMIT n [OFFSET skip]
The offset of the initial row is 0 (not 1).
428
Chapter 15
Limiting the Number of Rows Returned
Listing 15.26 List the top three salespeople, skipping
the initial four rows. See Figure 15.26 for the result.
SELECT emp_id, sales
FROM empsales

ORDER BY sales DESC
LIMIT 3 OFFSET 4;
Listing
emp_id sales

E01 600
E04 500
E03 500
Figure 15.26 Result of Listing 15.26.
Listing 15.27 List the top three salespeople, without
ties. See Figure 15.27 for the result.
SELECT emp_id, sales
FROM empsales
ORDER BY sales DESC
LIMIT 3;
Listing
emp_id sales

E09 900
E02 800
E05 700
Figure 15.27 Result of Listing 15.27.
✔ Tips

When using a inconsistent query to pre-
sent results to end-users, it’s a good practice
to include a tie-breaking
ORDER BY
column
so users see ties ranked consistently

across queries. Adding
emp_id
after
sales
in the (outermost)
ORDER BY
clause in the
queries in this section, for example, guar-
antees that employees with the same
sales
value always will sort the same way.

Fabian Pascal’s Practical Issues in
Database Management (Addison-Wesley)
discusses quota queries. His SQL-92
solution (which is too slow for practical
use) to list the top three salespeople,
including ties, is:
SELECT emp_id, sales
FROM empsales e1
WHERE (
SELECT COUNT(*)
FROM empsales e2
WHERE e2.sales > e1.sales
) < 3;
This query orders highest to lowest; to
reverse the order, change
>
to
<

in the
innermost
WHERE
clause.
429
SQL Tricks
Limiting the Number of Rows Returned
Listing 15.28 List the top three salespeople, with ties.
See Figure 15.28 for the result.
SELECT emp_id, sales
FROM empsales
WHERE (
sales >= (
SELECT sales
FROM empsales
ORDER BY sales DESC
LIMIT 1 OFFSET 2)
) IS NOT FALSE
ORDER BY sales DESC;
Listing
emp_id sales

E09 900
E02 800
E10 700
E05 700
Figure 15.28 Result of Listing 15.28.
Listing 15.29 List the top three salespeople, skipping
the initial four rows. See Figure 15.29 for the result.
SELECT emp_id, sales

FROM empsales
ORDER BY sales DESC
LIMIT 3 OFFSET 4;
Listing
emp_id sales

E01 600
E06 500
E03 500
Figure 15.29 Result of Listing 15.29.

×