This query orders highest to lowest; to reverse the order, change DESCtoASCin the ORDER BYclause.. This query orders highest to lowest; to reverse the order, change DESC toASCin the ORDE
Trang 1Listing 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
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.
Trang 2Limiting 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 BYclause SQL doesn’t require
anORDER BYclause, 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 BYclause)
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 empsalesactually 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,
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
UPDATEorDELETE(see Chapter 10)
Trang 3Microsoft 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 DESCtoASCin
the ORDER BYclause
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 ASCto
DESCin the ORDER BYclause
TheTOPclause 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
toDESCandDESCtoASCin 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;
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.
Trang 4Microsoft 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
BYsorts the table This query orders highest
to lowest; to reverse the order, change DESC
toASCin the ORDER BYclause
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 DESCtoASCin the ORDER BYclause
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.
Trang 5Listing 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 ASCto
DESCin the ORDER BYclause
TheTOPclause’s syntax is:
TOP n [PERCENT] [WITH TIES]
✔ Tips
■ The statement SET ROWCOUNT nprovides
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 ASCtoDESCandDESCtoASC
in each ORDER BYclause
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;
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.
Trang 6Use the built-in ROWNUMpseudocolumn to limit the number or rows returned The first row selected has a ROWNUMof 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
BYsorts the table This query orders highest
to lowest; to reverse the order, change DESC
toASCin the ORDER BYclause
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 DESCtoASCin the ORDER BYclause
✔ 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 DESCtoASCin the ORDER BYclause SELECT *
FROM ( SELECT ROW_NUMBER() OVER
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
Trang 7IBM 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
BYsorts the table This query orders highest
to lowest; to reverse the order, change DESC
toASCin the ORDER BYclause
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 DESCtoASCin the
ORDER BYclause
TheFETCHclause’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 DESCtoASCin 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;
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.
Trang 8MySQL 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
BYsorts the table This query orders highest
to lowest; to reverse the order, change DESC
toASCin the ORDER BYclause
Listing 15.25 lists the top three salespeople,
including ties The OFFSETvalue 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()toMAX()in the second subquery, and change DESCtoASC
in each ORDER BYclause
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
-
Trang 9-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 DESCtoASCin
the ORDER BYclause
TheLIMITclause’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
BYsorts the table This query orders highest
to lowest; to reverse the order, change DESC
toASCin the ORDER BYclause
Listing 15.28 lists the top three salespeople,
including ties The OFFSETvalue 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 DESCtoASCin each ORDER BYclause
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 DESCtoASCin
the ORDER BYclause
TheLIMITclause’s syntax is:
LIMIT n [OFFSET skip]
The offset of the initial row is 0 (not 1)
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.
Trang 10✔ Tips
■ When using a inconsistent query to pre-sent results to end-users, it’s a good practice
to include a tie-breaking ORDER BYcolumn
so users see ties ranked consistently across queries Adding emp_idafter sales
in the (outermost) ORDER BYclause 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 innermostWHEREclause
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