To filter rows by using a list:◆ Type: SELECT columns FROM table WHERE test_column [NOT] IN value1, value2,...; columns is one or more comma-separated column names, and table is the name
Trang 1✔ Tips
■ test_column can be an expression.
■ TheNOTthat can precede BETWEENis
independent of the NOTthat can precede
test_column; see the Tips in “Matching
Patterns with LIKE” earlier in this chapter
■ Listing 4.38 shows how to rewrite
Listing 4.36 with an exclusive range,
which doesn’t include the $10 and $19.95
endpoints See Figure 4.38 for the result.
■ Specifying a character range requires
some thought Suppose you want to
search for last names that begin with the
letter F The following clause won’t work
because it will retrieve someone whose
last name is the letter G (is the letter G,
not starts with the letter G):
WHERE last_name BETWEEN ‘F’ AND ‘G’
This next clause shows the correct way to
specify the ending point (in most cases):
WHERE last_name BETWEEN ‘F’ AND ‘Fz’
convert the floating-point num-bers in Listings 4.36 and 4.38 to DECIMAL;
see “Converting Data Types with CAST()”
in Chapter 5 To run Listings 4.36 and
4.38, change the floating-point literals to:
CAST(19.95 AS DECIMAL)
In Microsoft Access date literals, omit
the DATEkeyword and surround the
liter-al with # characters instead of quotes
To run Listing 4.37, change the dates in
the WHEREclause to #2000-01-01#and
#2000-12-31#
In Microsoft SQL Server and DB2 date
literals, omit the DATEkeyword To run
Listing 4.37, change the dates in the WHERE
clause to ‘2000-01-01’and‘2000-12-31’
In some DBMSs, low_value can exceed
high_value; search your DBMS
documen-tation for WHERE or BETWEEN.
Listing 4.38 List the titles priced between $10 and
$19.95, exclusive See Figure 4.38 for the result.
SELECT title_id, price FROM titles
WHERE (price > 10) AND (price < 19.95) ;
Listing
title_id price - -T04 12.99
T09 13.95
T12 12.99
Figure 4.38 Result of Listing 4.38.
Trang 2List Filtering with IN
Use INto determine whether a given value
matches any value in a specified list The IN condition’s important characteristics are:
◆ INworks with character strings, numbers, and datetimes
◆ TheINlist is a parenthesized listing of
one or more comma-separated values
The list items needn’t be in any
particu-lar order
◆ INis a convenient, shorthand clause that you can replicate by using OR
WHERE test_column IN
(value1, value2, value3)
is equivalent to:
WHERE (test_column = value1)
OR (test_column = value2)
OR (test_column = value3)
◆ String comparisons are case insensitive
or case sensitive, depending on your
DBMS; see the DBMS Tip in “Filtering
Rows with WHERE” earlier in this chapter
◆ You can negate an INcondition with
NOT IN
◆ You can combine INconditions and
other conditions with ANDandOR
Trang 3To filter rows by using a list:
◆ Type:
SELECT columns
FROM table
WHERE test_column [NOT] IN
(value1, value2, );
columns is one or more comma-separated
column names, and table is the name of
the table that contains columns.
In the search condition, test_column is the
name of a column in table (test_column
doesn’t have to be listed in columns), and
value1, value2, … are one or more
comma-separated values that are compared with
the value in test_column The list values
can appear in any order and must be the
same as or comparable to the data type of
test_column Specify NOT INto match
val-ues that aren’t in the list (Listings 4.39
through 4.41, Figures 4.39 through 4.41).
✔ Tips
■ test_column can be an expression.
■ TheNOTthat can precede INis
inde-pendent of the NOTthat can precede
test_column; see the Tips in “Matching
Patterns with LIKE” earlier in this chapter
■ If your list contains a large number of
values, your code will be easier to read
if you use one INcondition instead of
many ORconditions (Also, one INusually
runs faster than multiple ORs.)
■ For speed, list the most likely values first
If you’re testing U.S addresses, for
exam-ple, list the most populous states first:
WHERE state IN (‘CA’, ‘TX’, ‘NY’,
‘FL’, ,’VT’, ‘DC’, ‘WY’)
■ The search condition
WHERE col1 BETWEEN 1 AND 5
AND col1 <> 3
usually is faster than
WHERE col1 IN (1, 2, 4, 5)
Listing 4.39 List the authors who don’t live in New
York State, New Jersey, or California See Figure 4.39 for the result.
SELECT au_fname, au_lname, state FROM authors
WHERE state NOT IN ('NY', 'NJ', 'CA') ;
Listing
au_fname au_lname state - - -Wendy Heydemark CO
Paddy O'Furniture FL
Figure 4.39 Result of Listing 4.39.
Listing 4.40 List the titles for which advances of $0,
$1,000, or $5,000 were paid See Figure 4.40 for the result.
SELECT title_id, advance FROM royalties WHERE advance IN (0.00, 1000.00, 5000.00) ;
Listing
title_id advance - -T02 1000.00
T08 0.00
T09 0.00
Figure 4.40 Result of Listing 4.40.
Trang 4■ A compound condition’s order of evalua-tion is easier to read and manage if you use
INinstead of multiple ORs; see “Combining and Negating Conditions with AND,OR, andNOT” earlier in this chapter
■ You also can use INto determine whether
a given value matches any value in a sub-query; see Chapter 8
■ NOT INis equivalent to combining tests for inequality with AND This statement is equivalent to Listing 4.39:
SELECT au_fname, au_lname, state FROM authors
WHERE state <> ‘NY’
AND state <> ‘NJ’
AND state <> ‘CA’;
literals, omit the DATEkeyword and surround the literal with # charac-ters instead of quotes To run Listing 4.41, change the WHEREclause to:
WHERE pubdate IN (#1/1/2000#,
#1/1/2001#,
#1/1/2002#)
In Microsoft SQL Server and DB2 date
literals, omit the DATEkeyword To run Listing 4.41, change the WHEREclause to:
WHERE pubdate IN (‘2000-01-01’,
‘2001-01-01’,
‘2002-01-01’)
In older PostgreSQL versions, convert
the floating-point number in Listing 4.40
toDECIMAL; see “Converting Data Types with CAST()” in Chapter 5 To run Listing 4.40, change the WHEREclause to:
WHERE advance IN (CAST( 0.00 AS DECIMAL), CAST(1000.00 AS DECIMAL), CAST(5000.00 AS DECIMAL))
Listing 4.41 List the titles published on the first day of
the year 2000, 2001, or 2002 See Figure 4.41 for the
result.
SELECT title_id, pubdate
FROM titles
WHERE pubdate IN
(DATE '2000-01-01',
DATE '2001-01-01',
DATE '2002-01-01') ;
Listing
title_id pubdate
-
-T05 2001-01-01
Figure 4.41 Result of Listing 4.41.
Trang 5Testing for Nulls
Recall from “Nulls” in Chapter 3 that nulls
represent missing or unknown values This
situation causes a problem: LIKE,BETWEEN,
IN, and other WHERE-clause conditions can’t
find nulls because unknown values don’t
satisfy specific conditions A null matches
no value—not even other nulls You can’t
use=or<>to test whether a value is null
In the table publishers, for example, note
that publisher P03 has a null in the column
statebecause that column doesn’t apply to
Germany (Listing 4.42 and Figure 4.42).
I can’t use complementary comparisons to
select the null, because null is neither California
nor not-California; it’s undefined (Listings
4.43 and 4.44, Figures 4.43 and 4.44).
To avert disaster, SQL provides IS NULLto
determine whether a given value is null
TheIS NULLcondition’s important
character-istics are:
◆ IS NULLworks for columns of any
data type
◆ You can negate an IS NULLcondition
with IS NOT NULL
◆ You can combine IS NULLconditions
and other conditions with ANDandOR
Listing 4.42 List the locations of all the publishers.
See Figure 4.42 for the result.
SELECT pub_id, city, state, country FROM publishers;
Listing
pub_id city state country - - - -P01 New York NY USA P02 San Francisco CA USA P03 Hamburg NULL Germany P04 Berkeley CA USA
Figure 4.42 Result of Listing 4.42 The column state
doesn’t apply to the publisher located in Germany.
Listing 4.43 List the publishers located in California.
See Figure 4.43 for the result.
SELECT pub_id, city, state, country FROM publishers
WHERE state = 'CA' ;
Listing
pub_id city state country - - - -P02 San Francisco CA USA P04 Berkeley CA USA
Figure 4.43 Result of Listing 4.43 This result doesn’t
include publisher P03.
Trang 6To retrieve rows with nulls or non-null values:
SELECT columns FROM table WHERE test_column IS [NOT] NULL;
columns is one or more comma-separated column names, and table is the name of the table that contains columns.
In the search condition, test_column
is the name of a column in table.
(test_column doesn’t have to be listed
in columns.) Specify NOT NULLto match
non-null values (Listings 4.45 and 4.46,
Figures 4.45 and 4.46).
Listing 4.44 List the publishers located outside
California (the wrong way—see Listing 4.45 for the
correct way) See Figure 4.44 for the result.
SELECT pub_id, city, state, country
FROM publishers
WHERE state <> 'CA' ;
Listing
pub_id city state country
- - -
-P01 New York NY USA
Figure 4.44 Result of Listing 4.44 This result doesn’t
include publisher P03 either The conditions state =
‘CA’ and state <> ‘CA’ aren’t complementary after all;
nulls don’t match any value and so can’t be selected by
using the types of conditions I’ve covered so far.
Listing 4.45 List the publishers located outside
California (the correct way) See Figure 4.45 for the
result.
SELECT pub_id, city, state, country
FROM publishers
WHERE state <> 'CA'
OR state IS NULL ;
Listing
pub_id city state country
- - -
-P01 New York NY USA
P03 Hamburg NULL Germany
Figure 4.45 Result of Listing 4.45 Now publisher P03
is in the result.
title_id type pubdate - - -T06 biography 2000-07-31
T07 biography 1999-10-01
T12 biography 2000-08-31
Figure 4.46 Result of Listing 4.46 Without the
IS NOT NULL condition, this result would have included title T10.
Listing 4.46 List the biographies whose (past or
future) publication dates are known See Figure 4.46 for the result.
SELECT title_id, type, pubdate FROM titles
WHERE type = 'biography' AND pubdate IS NOT NULL ;
Listing
Trang 7✔ Tips
■ test_column can be an expression.
■ TheNOTthat can precede NULLis inde-pendent of the NOTthat can precede
test_column; see the Tips in “Matching
Patterns with LIKE” earlier in this chapter
■ Nulls cause rows to be excluded from results only if a column containing nulls
is a test column in a WHEREcondition The following query, for example, retrieves all the rows in the table publishers(refer
to Figure 4.42) because the null in the col-umnstateisn’t compared with anything: SELECT pub_id, city, state, country FROM publishers
WHERE country <> ‘Canada’;
To forbid nulls in a column, see
“Forbidding Nulls with NOT NULL” in Chapter 11
■ It bears repeating that a null isn’t the same as an empty string (‘’) In the table authors, for example, the column au_fnamecontains an empty string for author A06 (last name of Kellsey) The WHEREcondition to find the first name is WHERE au_fname = ‘’
and not
WHERE au_fname IS NULL
(‘’) as a null; see the DBMS Tip
in “Nulls” in Chapter 3
Trang 8Operators and functions let you calculate results derived from column values, system-determined values, constants, and other data You can perform:
◆ Arithmetic operations—Cut everyone’s salary by 10 percent
◆ String operations—Concatenate personal information into a mailing address
◆ Datetime operations—Compute the time interval between two dates
◆ System operations—Find out what time your DBMS thinks it is
An operator is a symbol or keyword
indicat-ing an operation that acts on one or more
elements The elements, called operands, are
SQL expressions Recall from the “SQL Syntax” Tips in Chapter 3 that an expression
is any legal combination of symbols and tokens that evaluates to a single value (or null) In price * 2, for example, *is the oper-ator, and priceand2are its operands
A function is a built-in, named routine that
performs a specialized task Most functions
take parenthesized arguments, which are values
you pass to the function that the function then uses to perform its task Arguments can
be column names, literals, nested functions, or more-complex expressions In UPPER(au_lname), for example, UPPERis the function name, and au_lnameis the argument
Operators
and Functions
5
Trang 9Creating Derived Columns
You can use operators and functions to
create derived columns A derived column
is the result of a calculation and is created
with a SELECT-clause expression that is
something other than a simple reference to
a column Derived columns don’t become
permanent columns in a table; they’re for
display and reporting purposes
The values in a derived column often are
computed from values in existing columns,
but you also can create a derived column by
using a constant expression (such as a string,
number, or date) or system value (such as
the system time) Listing 5.1 shows a
SELECTstatement that yields a trivial
arith-metic calculation; it needs no FROMclause
because it doesn’t retrieve data from a table
Figure 5.1 shows the result.
Recall from “Tables, Columns, and Rows” in
Chapter 2 that closure guarantees that every
result is a table, so even this simple result is
a table: a 1 ✕1 table that contains the value 5
If I retrieve a column along with a constant,
the constant appears in every row of the
result (Listing 5.2 and Figure 5.2).
Your DBMS will assign the derived column a
default name, typically the expression itself as
a quoted identifier You should name derived
columns explicitly with an ASclause because
system-assigned names can be long, unwieldy,
and inconvenient for database applications to
refer to; see “Creating Column Aliases with AS”
in Chapter 4 (Listing 5.3 and Figure 5.3).
No FROM clause is needed, because I’m not retrieving data from a table See Figure 5.1 for the result.
SELECT 2 + 3 ;
Listing
2 + 3 -5
Figure 5.1 Result of Listing 5.1 This result is a table
with one row and one column.
Listing 5.2 Here, I’ve retrieved a column and a
constant expression See Figure 5.2 for the result.
SELECT au_id, 2 + 3 FROM authors;
Listing
au_id 2 + 3 -A01 5 A02 5 A03 5 A04 5 A05 5 A06 5 A07 5
Figure 5.2 Result of Listing 5.2 The constant is
repeated in each row.
Trang 10✔ Tip
■ Oracle requires a FROMclause
in a SELECTstatement and so
creates the dummy tableDUAL automati-cally to be used for SELECTing a constant expression; search Oracle documentation
for DUAL table To run Listing 5.1, add a
FROMclause that selects the constant value fromDUAL:
SELECT 2 + 3 FROM DUAL;
DB2 requires a FROMclause in a SELECT statement and so creates the dummy table SYSIBM.SYSDUMMY1automatically to
be used for SELECTing a constant expres-sion; search DB2 documentation for
SYSIBM.SYSDUMMY1 To run Listing 5.1,
add a FROMclause that selects the con-stant value from SYSIBM.SYSDUMMY1: SELECT 2 + 3
FROM SYSIBM.SYSDUMMY1 ;
In older PostgreSQL versions, convert
the floating- point number in Listing 5.3
toDECIMAL; see “Converting Data Types with CAST()” later in this chapter To run Listing 5.3, change the New price calcula-tion in the SELECTclause to:
price * CAST((1 - 0.10) AS DECIMAL)
Listing 5.3 List the book prices discounted by 10
percent The derived columns would have
DBMS-specific default names if the AS clauses were
removed See Figure 5.3 for the result.
SELECT title_id,
price,
0.10 AS "Discount" ,
price * (1 - 0.10) AS "New price"
FROM titles;
Listing
title_id price Discount New price
- - -
-T01 21.99 0.10 19.79
T02 19.95 0.10 17.95
T03 39.95 0.10 35.96
T04 12.99 0.10 11.69
T05 6.95 0.10 6.25
T06 19.95 0.10 17.95
T07 23.95 0.10 21.56
T08 10.00 0.10 9.00
T09 13.95 0.10 12.56
T10 NULL 0.10 NULL
T11 7.99 0.10 7.19
T12 12.99 0.10 11.69
T13 29.99 0.10 26.99
Figure 5.3 Result of Listing 5.3.