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

SQL VISUAL QUICKSTART GUIDE- P16 ppt

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 (191.57 KB, 10 trang )

Performing Arithmetic
Operations
A monadic (or unary) arithmetic operator
performs a mathematical operation on a
single numeric operand to produce a result.
The
-
(negation) operator changes the sign
of its operand, and the not-very-useful
+
(identity) operator leaves its operand
unchanged. A dyadic (or binary) arithmetic
operator performs a mathematical operation
on two numeric operands to produce a result.
These operators include the usual ones:
+
(addition),
-
(subtraction),
*
(multiplication),
and
/
(division). Table 5.1 lists SQL’s arith-
metic operators (expr is a numeric expression).
To change the sign of a number:

Type
-expr
expr is a numeric expression (Listing 5.4
and Figure 5.4).


130
Chapter 5
Performing Arithmetic Operations
Table 5.1
Arithmetic Operators
Operator What It Does
-expr
Reverses the sign of expr
+expr
Leaves expr unchanged
expr1 + expr2
Sums expr1 and expr2
expr1 – expr2
Subtracts expr2 from expr1
expr1 * expr2
Multiplies expr1 and expr2
expr1 / expr2
Divides expr1 by expr2
Listing 5.4 The negation operator changes the sign of
a number. See Figure 5.4 for the result.
SELECT title_id,
-advance AS "Advance"
FROM royalties;
Listing
title_id Advance

T01 -10000.00
T02 -1000.00
T03 -15000.00
T04 -20000.00

T05 -100000.00
T06 -20000.00
T07 -1000000.00
T08 0.00
T09 0.00
T10 NULL
T11 -100000.00
T12 -50000.00
T13 -20000.00
Figure 5.4 Result of Listing 5.4. Note that zero has no
sign (is neither positive nor negative).
To add, subtract, multiply, or divide:

Type
expr1+expr2
to add,
expr1-expr2
to
subtract,
expr1*expr2
to multiply, or
expr1/expr2
to divide.
expr1 and expr2 are numeric expressions
(Listing 5.5 and Figure 5.5).
✔ Tips

The result of any arithmetic operation
that involves a null is null.


If you use multiple operators in a single
expression, you may need to use paren-
theses to control the calculation order; see
“Determining the Order of Evaluation”
later in this chapter.

If you mix numeric data types in an
arithmetic expression, your DBMS con-
verts, or coerces, all the numbers to the
data type of the expression’s most com-
plex operand and returns the result in
this type. This conversion process is
called promotion. If you add an
INTEGER
and a
FLOAT
, for example, the DBMS con-
verts the integer to a float, adds the
numbers, and returns the sum as a float.
In some cases, you must convert a data
type to another data type explicitly; see
“Converting Data Types with
CAST()

later in this chapter.
continues on next page
131
Operators and Functions
Performing Arithmetic Operations
Listing 5.5 List the biographies by descending

revenue (= price x sales). See Figure 5.5 for the result.
SELECT title_id,
price * sales AS "Revenue"
FROM titles
WHERE type = 'biography'
ORDER BY price * sales DESC;
Listing
title_id Revenue

T07 35929790.00
T12 1299012.99
T06 225834.00
T10 NULL
Figure 5.5 Result of Listing 5.5.
Other Operators and Functions
All DBMSs provide plenty of operators
and functions in addition to those
defined in the SQL standard (or covered
in this book). In fact, the standard is play-
ing catch-up—many of the functions
introduced in the latest standard have
existed for years in DBMSs. The earlier
standards were so anemic that they left
SQL weaker than a desktop calculator. If
you search your DBMS documentation
for operators and functions, you’ll find
mathematical, statistical, financial, scien-
tific, trigonometric, conversion, string,
datetime, bitwise, system, metadata,
security, and other entries.


If you’re writing a database application or
UPDATE
ing rows, note that data types aren’t
closed for some arithmetic operations.
If you multiply or add two
SMALLINT
s, for
example, the result might be greater than
a
SMALLINT
column can hold. Similarly,
dividing two
INTEGER
s doesn’t necessarily
yield an
INTEGER
.

Sometimes DBMSs force mathe-
matical closure, so be careful
when dividing integers by integers. If an
integer dividend is divided by an integer
divisor, the result may be an integer that
has any fractional part of the result trun-
cated. You might expect the two derived
columns in Listing 5.6 to contain the
same values, because the column
pages
(an

INTEGER
) is divided by two equal
constants: 10 (an integer) and 10.0 (a
float). Microsoft Access, Oracle, and
MySQL return the result you’d expect
(Figure 5.6a), but Microsoft SQL Server,
DB2, and PostgreSQL truncate the result
of an integer division (Figure 5.6b).
132
Chapter 5
Performing Arithmetic Operations
Listing 5.6 This query’s first derived column
divides
pages
by the integer constant 10, and the
second derived column divides
pages
by the
floating-point constant 10.0. In the result, you’d
expect identical values to be in both derived
columns. See Figures 5.6a and 5.6b for the results.
SELECT title_id,
pages,
pages/10 AS "pages/10",
pages/10.0 AS "pages/10.0"
FROM titles;
Listing
title_id pages pages/10 pages/10.0

T01 107 10.7 10.7

T02 14 1.4 1.4
T03 1226 122.6 122.6
T04 510 51.0 51.0
T05 201 20.1 20.1
T06 473 47.3 47.3
T07 333 33.3 33.3
T08 86 8.6 8.6
T09 22 2.2 2.2
T10 NULL NULL NULL
T11 826 82.6 82.6
T12 507 50.7 50.7
T13 802 80.2 80.2
Figure 5.6a Result of Listing 5.6 for Microsoft Access,
Oracle, and MySQL. Dividing two integers yields a
floating-point number (as you’d expect).
title_id pages pages/10 pages/10.0

T01 107 10 10.7
T02 14 1 1.4
T03 1226 122 122.6
T04 510 51 51.0
T05 201 20 20.1
T06 473 47 47.3
T07 333 33 33.3
T08 86 8 8.6
T09 22 2 2.2
T10 NULL NULL NULL
T11 826 82 82.6
T12 507 50 50.7
T13 802 80 80.2

Figure 5.6b Result of Listing 5.6 for Microsoft SQL
Server, DB2, and PostgreSQL. Dividing two integers
yields an integer; the fractional part of the result is
discarded (not as you’d expect).
Determining the Order
of Evaluation
Precedence determines the priority of vari-
ous operators when more than one operator
is used in an expression. Operators with
higher precedence are evaluated first.
Arithmetic operators (
+
,
-
,
*
, and so on) have
higher precedence than comparison opera-
tors (
<
,
=
,
>
, and so on), which have higher
precedence than logical operators (
NOT
,
AND
,

OR
), so the expression
a or b * c >= d
is equivalent to
a or ((b * c) >= d)
Operators with lower precedence are less
binding than those with higher precedence.
Table 5.2 lists operator precedences from
most to least binding. Operators in the same
row have equal precedence.
Associativity determines the order of
evaluation in an expression when adjacent
operators have equal precedence. SQL uses
left-to-right associativity.
You don’t need to memorize all this
information. You can use parentheses to
override precedence and associativity rules
(Listing 5.7 and Figure 5.7).
✔ Tips

Table 5.2 is incomplete; it omits
some standard (such as
IN
and
EXISTS
) and nonstandard (DBMS-specific)
operators. To determine the complete
order of evaluation that your DBMS uses,
search your DBMS documentation for
precedence.

To run Listing 5.7 in Oracle, add the
clause
FROM DUAL
. To run it in DB2, add
the clause
FROM
SYSIBM.SYSDUMMY1
. See
the DBMS Tip in “Creating Derived
Columns” earlier in this chapter.
133
Operators and Functions
Determining the Order of Evaluation
Table 5.2
Order of Evaluation (Highest to Lowest)
Operator Description
+
,
-
Monadic identity, monadic negation
*
,
/
Multiplication, division
+
,
-
Addition, subtraction
=
,

<>
,
<
,
<=
,
>
,
>=
Comparison operators
NOT
Logical
NOT
AND
Logical
AND
OR
Logical
OR
Listing 5.7 The first and second columns show how
to use parentheses to override precedence rules.
The third and fourth columns show how to use
parentheses to override associativity rules. See
Figure 5.7 for the result.
SELECT 2 + 3 * 4 AS "2+3*4",
(2 + 3) * 4 AS "(2+3)*4",
6 / 2 * 3 AS "6/2*3",
6 / (2 * 3) AS "6/(2*3)";
Listing
2+3*4 (2+3)*4 6/2*3 6/(2*3)


14 20 9 1
Figure 5.7 Result of Listing 5.7.

It’s good programming style to add
parentheses (even when they’re unneces-
sary) to complex expressions to ensure
your intended evaluation order and make
code more portable and easier to read.
Concatenating Strings
with ||
Use the operator
||
to combine, or concate-
nate, strings. The operator’s important char-
acteristics are:

The operator
||
is two consecutive
vertical-bar, or pipe, characters.

Concatenation doesn’t add a space
between strings.

||
, a dyadic operator, combines two
strings into a single string:
‘formal’
|| ‘dehyde’

is
‘formaldehyde’
.

You can chain concatenations to com-
bine multiple strings into a single string:
‘a’ || ‘b’ || ‘c’ || ‘d’
is
‘abcd’
.

Concatenation with an empty string (
‘’
)
leaves a string unchanged:
‘a’ || ‘’ ||
‘b’
is
‘ab’
.

The result of any concatenation opera-
tion that involves a null is null:
‘a’ ||
NULL || ‘b’
is
NULL
. (But see the
Oracle exception in the DBMS Tip in
this section.)


To concatenate a string and a nonstring
(such as a numeric or datetime value),
you must convert the nonstring to a
string if your DBMS doesn’t convert it
implicitly; see “Converting Data Types
with
CAST()
” later in this chapter.
134
Chapter 5
Concatenating Strings with ||
Listing 5.8 List the authors’ first and last names,
concatenated into a single column and sorted by last
name/first name. See Figure 5.8 for the result.
SELECT au_fname || ' ' || au_lname
AS "Author name"
FROM authors
ORDER BY au_lname ASC, au_fname ASC;
Listing
Author name

Sarah Buchman
Wendy Heydemark
Hallie Hull
Klee Hull
Christian Kells
Kellsey
Paddy O'Furniture
Figure 5.8 Result of Listing 5.8.

Listing 5.9 List biography sales by descending sales
order. Here, I need to convert
sales
from an integer to
a string. See Figure 5.9 for the result.
SELECT CAST(sales AS CHAR(7))
|| ' copies sold of title '
|| title_id
AS "Biography sales"
FROM titles
WHERE type = 'biography'
AND sales IS NOT NULL
ORDER BY sales DESC;
Listing
Biography sales

1500200 copies sold of title T07
100001 copies sold of title T12
11320 copies sold of title T06
Figure 5.9 Result of Listing 5.9.
To concatenate strings:

Type:
string1 || string2
string1 and string2 are the strings to be
combined. Each operand is a string
expression such as a column that con-
tains character strings, a string literal,
or the result of an operation or function
that returns a string (Listings 5.8 through

5.11, Figures 5.8 through 5.11).
✔ Tips

You can use
||
in
SELECT
,
WHERE
, and
ORDER BY
clauses or anywhere an expres-
sion is allowed.

You can concatenate hex and bit strings:
B’0100’ || B’1011’
is
B’01001011’
.

Listing 5.11 shows how to use
||
in a
WHERE
clause, but it’s actually bad SQL.
The efficient way to express the clause is:
WHERE au_fname = ‘Klee’
AND au_lname = ‘Hull’

You can use the

TRIM()
function to
remove unwanted spaces from concate-
nated strings. Recall from “Character
String Types” in Chapter 3 that
CHAR
values are padded with trailing spaces,
sometimes creating long, ugly stretches
of spaces in concatenated strings.
TRIM()
will remove the extra space in front of
the name Kellsey in Figure 5.8, for exam-
ple; see “Trimming Characters with
TRIM()
” later in this chapter.
continues on next page
135
Operators and Functions
Concatenating Strings with ||
Listing 5.10 List biographies by descending publication
date. Here, I need to convert
pubdate
from a datetime
to a string. See Figure 5.10 for the result.
SELECT 'Title '
|| title_id
|| ' published on '
|| CAST(pubdate AS CHAR(10))
AS "Biography publication dates"
FROM titles

WHERE type = 'biography'
AND pubdate IS NOT NULL
ORDER BY pubdate DESC;
Listing
Biography publication dates

Title T12 published on 2000-08-31
Title T06 published on 2000-07-31
Title T07 published on 1999-10-01
Figure 5.10 Result of Listing 5.10.
Listing 5.11 List all the authors named Klee Hull. See
Figure 5.11 for the result.
SELECT au_id, au_fname, au_lname
FROM authors
WHERE au_fname || ' ' || au_lname
= 'Klee Hull';
Listing
au_id au_fname au_lname

A04 Klee Hull
Figure 5.11 Result of Listing 5.11.

In Microsoft Access, the con-
catenation operator is
+
, and the
conversion function is
Format(string)
.
To run Listings 5.8 through 5.11, change

the concatenation and conversion
expressions to (Listing 5.8):
au_fname + ‘ ‘ + au_lname
and (Listing 5.9):
Format(sales)

+ ‘ copies sold of title ‘

+ title_id
and (Listing 5.10):
‘Title ‘

+ title_id

+ ‘ published on ‘

+ Format(pubdate)
and (Listing 5.11):
au_fname + ‘ ‘ + au_lname

= ‘Klee Hull’;
In Microsoft SQL Server, the concate-
nation operator is
+
. To run Listings 5.8
through 5.11, change the concatenation
expressions to (Listing 5.8):
au_fname + ‘ ‘ + au_lname
and (Listing 5.9):
CAST(sales AS CHAR(7))


+ ‘ copies sold of title ‘

+ title_id
and (Listing 5.10):
‘Title ‘

+ title_id

+ ‘ published on ‘

+ CAST(pubdate AS CHAR(10))
and (Listing 5.11):
au_fname + ‘ ‘ + au_lname

= ‘Klee Hull’;
In MySQL, the concatenation function is
CONCAT()
. The
||
operator is legal, but it
means logical
OR
in MySQL by default. (Use
PIPES_AS_CONCAT
mode to treat
||
as a
string-concatenation operator rather than
as a synonym for

OR
.)
CONCAT()
takes any
number of arguments and converts non-
strings to strings as necessary (so
CAST()
isn’t needed). To run Listings 5.8 through
5.11, change the concatenation expressions
to (Listing 5.8):
CONCAT(au_fname, ‘ ‘, au_lname)
and (Listing 5.9):
CONCAT(sales,

’ copies sold of title ‘
,

title_id)
and (Listing 5.10):
CONCAT(‘Title ‘,

title_id,

’ published on ‘,

pubdate)
and (Listing 5.11):
CONCAT(au_fname, ‘ ‘, au_lname)

= ‘Klee Hull’;

Oracle treats an empty string as null:
‘a’
|| NULL || ‘b’
returns
‘ab’
. See the DBMS
Tip in “Nulls” in Chapter 3.
Oracle, MySQL, and PostgreSQL convert
nonstrings to strings implicitly in concat-
enations; Listings 5.9 and 5.10 still will run
on these DBMSs if you omit
CAST()
. Search
your DBMS documentation for concatenation
or conversion.
Oracle and DB2 also support the
CONCAT()
function.
136
Chapter 5
Concatenating Strings with ||
Extracting a Substring
with SUBSTRING()
Use the function
SUBSTRING()
to extract part
of a string. The function’s important charac-
teristics are:

A substring is any sequence of contigu-

ous characters from the source string,
including an empty string or the entire
source string itself.

SUBSTRING()
extracts part of a string
starting at a specified position and
continuing for a specified number of
characters.

A substring of an empty string is an
empty string.

If any argument is null,
SUBSTRING()
returns null. (But see the Oracle excep-
tion in the DBMS Tip in this section.)
To extract a substring:

Type:
SUBSTRING(string FROM start [FOR
length])
string is the source string from which to
extract the substring. string is a string
expression such as a column that con-
tains character strings, a string literal, or
the result of an operation or function that
returns a string. start is an integer that
specifies where the substring begins, and
length is an integer that specifies the

length of the substring (the number of
characters to return). start starts counting
at 1. If
FOR length
is omitted,
SUBSTRING()
returns all the characters from start to
the end of string (Listings 5.12 through
5.14, Figures 5.12 through 5.14).
137
Operators and Functions
Extracting a Substring with SUBSTRING()
Listing 5.12 Split the publisher IDs into alphabetic
and numeric parts. The alphabetic part of a publisher
ID is the first character, and the remaining characters
are the numeric part. See Figure 5.12 for the result.
SELECT pub_id,
SUBSTRING(pub_id FROM 1 FOR 1)
AS "Alpha part",
SUBSTRING(pub_id FROM 2)
AS "Num part"
FROM publishers;
Listing
pub_id Alpha part Num part

P01 P 01
P02 P 02
P03 P 03
P04 P 04
Figure 5.12 Result of Listing 5.12.

Listing 5.13 List the first initial and last name of the
authors from New York State and Colorado. See
Figure 5.13 for the result.
SELECT SUBSTRING(au_fname FROM 1 FOR 1)
|| '. '
|| au_lname
AS "Author name",
state
FROM authors
WHERE state IN ('NY', 'CO');
Listing
Author name state

S. Buchman NY
W. Heydemark CO
C. Kells NY
Figure 5.13 Result of Listing 5.13.
✔ Tips

You can use
SUBSTRING()
in
SELECT
,
WHERE
, and
ORDER BY
clauses or anywhere
an expression is allowed.


You can extract substrings from hex and
bit strings:
SUBSTRING(B’01001011’ FROM
5 FOR 4)
returns
B’1011’
.

In Microsoft Access, the sub-
string function is
Mid(string,
start [,length])
. Use
+
to concatenate
strings. To run Listings 5.12 through 5.14,
change the substring expressions to
(Listing 5.12):
Mid(pub_id, 1, 1)
Mid(pub_id, 2)
and (Listing 5.13):
Mid(au_fname, 1, 1) + ‘. ‘ + au_lname
and (Listing 5.14):
Mid(phone, 1, 3)=’415’
In Microsoft SQL Server, the substring
function is
SUBSTRING(string, start,
length)
. Use
+

to concatenate strings. To
run Listings 5.12 through 5.14, change the
substring expressions to (Listing 5.12):
SUBSTRING(pub_id, 1, 1)
SUBSTRING(pub_id, 2, LEN(pub_id)-1)
and (Listing 5.13):
SUBSTRING(au_fname, 1, 1)

+ ‘. ‘

+ au_lname
and (Listing 5.14):
SUBSTRING(phone, 1, 3)=’415’
138
Chapter 5
Extracting a Substring with SUBSTRING()
Listing 5.14 List the authors whose area code is 415.
See Figure 5.14 for the result.
SELECT au_fname, au_lname, phone
FROM authors
WHERE SUBSTRING(phone FROM 1 FOR 3)='415';
Listing
au_fname au_lname phone

Hallie Hull 415-549-4278
Klee Hull 415-549-4278
Figure 5.14 Result of Listing 5.14.
In Oracle and DB2, the substring function
is
SUBSTR(string, start [,length])

. To run
Listings 5.12 through 5.14, change the sub-
string expressions to (Listing 5.12):
SUBSTR(pub_id, 1, 1)
SUBSTR(pub_id, 2)
and (Listing 5.13):
SUBSTR(au_fname, 1, 1)

|| ‘. ‘

|| au_lname
and (Listing 5.14):
SUBSTR(phone, 1, 3)=’415’
In MySQL, use
CONCAT()
to run Listing 5.13
(see “Concatenating Strings with
||
” earlier
in this chapter). Change the concatenation
expression to:
CONCAT(

SUBSTRING(au_fname FROM 1 FOR 1),

’. ‘,

au_lname)
Oracle treats an empty string as null:
SUBSTR(NULL, 1, 2)

returns
‘’
. See the
DBMS Tip in “Nulls” in Chapter 3.
Your DBMS implicitly might constrain start
and length arguments that are too small or
too large to sensible values. The substring
function silently may replace a negative start
with 1 or a too-long length with the length of
string, for example. Search your DBMS docu-
mentation for substring or substr.
MySQL and PostgreSQL also support the
SUBSTR(string, start, length)
form of the
substring function.
139
Operators and Functions
Extracting a Substring with SUBSTRING()

×