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

SQL VISUAL QUICKSTART GUIDE- P19 doc

10 226 0

Đ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 196,22 KB

Nội dung

In Microsoft SQL Server, use + to concate- nate strings (Listing 5.28): ‘<’ + CAST(price AS CHAR(8)) + ‘>’ and (Listing 5.29): CAST(sales AS CHAR(8)) ➝ + ‘ copies sold of ‘ ➝ + CAST(title_name AS CHAR(20)) Oracle doesn’t allow character conversions to CHAR(length) if length is shorter than the source string. Instead, use SUBSTR() to trun- cate strings; see the DBMS Tip in “Extracting a Substring with SUBSTRING() ” earlier in this chapter. To run Listing 5.29, change the CAST() expression to: CAST(sales AS CHAR(8)) ➝ || ‘ copies sold of ‘ ➝ || SUBSTR(title_name, 1, 20) In MySQL, use SIGNED instead of INTEGER for data_type, and use CONCAT() to concatenate strings. To run Listings 5.28 and 5.29, change the CAST() expressions to (Listing 5.28): CAST(price AS SIGNED) CONCAT(‘<’, CAST(price AS CHAR(8)), ➝ ’>’) and (Listing 5.29): CONCAT( ➝ CAST(sales AS CHAR(8)), ➝ ’ copies sold of ‘, ➝ CAST(title_name AS CHAR(20))) Oracle treats an empty string as null: CAST(‘’ AS CHAR) returns null. See the DBMS Tip in “Nulls” in Chapter 3. In older PostgreSQL versions, to compare a value in a NUMERIC or DECIMAL column with a real (floating-point) number, you must convert the real number to NUMERIC or DECIMAL explicitly. The following statement, for example, fails in older PostgreSQL ver- sions, because the data type of the column price is DECIMAL(5,2) : SELECT price FROM titles WHERE price < 20.00; This statement fixes the problem: SELECT price FROM titles WHERE price < CAST(20.00 AS DECIMAL); DBMSs have additional conversion and formatting functions. Some examples: CONVERT() in Microsoft SQL Server and MySQL; TO_CHAR() , TO_DATE() , TO_TIMESTAMP() , and TO_NUMBER() in Oracle and PostgreSQL; and TO_CHAR() and TO_DATE() in DB2. Search your DBMS documentation for conversion, cast, or formatting functions. 160 Chapter 5 Converting Data Types with CAST() Evaluating Conditional Values with CASE The CASE expression and its shorthand equiv- alents, COALESCE() and NULLIF() , let you take actions based on a condition’s truth value (true, false, or unknown). The CASE expres- sion’s important characteristics are: ◆ If you’ve programmed before, you’ll recognize that CASE provides SQL the equivalent of the if-then-else , case , or switch statements used in procedural languages, except that CASE is an expres- sion, not a statement. ◆ CASE is used to evaluate several condi- tions and return a single value for the first true condition. ◆ CASE allows you to display an alternative value to the actual value in a column. CASE makes no changes to the underly- ing data. ◆ Acommon use of CASE is to replace codes or abbreviations with more-readable values. If the column marital_status contains the integer codes 1, 2, 3, or 4— meaning single, married, divorced, or widowed—your human readers will pre- fer to see explanatory text rather than cryptic codes. (Some database designers prefer to use codes, because it’s more effi- cient to store and manage abbreviated codes than explanatory text.) ◆ CASE has two formats: simple and searched. The simple CASE expression compares an expression to a set of sim- ple expressions to determine the result. The searched CASE expression evaluates a set of logical (Boolean) expressions to determine the result. ◆ CASE returns an optional ELSE result as the default value if no test condition is true. 161 Operators and Functions Evaluating Conditional Values with CASE To use a simple CASE expression: ◆ Type: CASE comparison_value WHEN value1 THEN result1 WHEN value2 THEN result2 WHEN valueN THEN resultN [ELSE default_result] END value1, value2, , valueN are expressions. result1, result2, , resultN are expressions returned when the corresponding value matches the expression comparison_value. All expressions must be of the same type or must be implicitly convertible to the same type. Each value is compared to comparison_ value in order. First, value1 is compared. If it matches comparison_value, then result1 is returned; otherwise, value2 is compared to comparison_value. If value2 matches comparison_value, then result2 is returned, and so on. If no matches occur, default_ result is returned. If ELSE default_result is omitted, ELSE NULL is assumed (Listing 5.30 and Figure 5.30). 162 Chapter 5 Evaluating Conditional Values with CASE Listing 5.30 Raise the price of history books by 10 percent and psychology books by 20 percent, and leave the prices of other books unchanged. See Figure 5.30 for the result. SELECT title_id, type, price, CASE type WHEN 'history' THEN price * 1.10 WHEN 'psychology' THEN price * 1.20 ELSE price END AS "New price" FROM titles ORDER BY type ASC, title_id ASC; Listing title_id type price New price T06 biography 19.95 19.95 T07 biography 23.95 23.95 T10 biography NULL NULL T12 biography 12.99 12.99 T08 children 10.00 10.00 T09 children 13.95 13.95 T03 computer 39.95 39.95 T01 history 21.99 24.19 T02 history 19.95 21.95 T13 history 29.99 32.99 T04 psychology 12.99 15.59 T05 psychology 6.95 8.34 T11 psychology 7.99 9.59 Figure 5.30 Result of Listing 5.30. To use a searched CASE expression: ◆ Type: CASE WHEN condition1 THEN result1 WHEN condition2 THEN result2 WHEN conditionN THEN resultN [ELSE default_result] END condition1, condition2, , conditionN are search conditions. (Search conditions have one or more logical expressions, with multiple expressions linked by AND or OR ; see “Filtering Rows with WHERE ” in Chapter 4.) result1, result2, , resultN are expressions returned when the corre- sponding condition evaluates to true. All expressions must be of the same type or must be implicitly convertible to the same type. Each condition is evaluated in order. First, condition1 is evaluated. If it’s true, result1 is returned; otherwise, condition2 is evaluated. If condition2 is true, result2 is returned, and so on. If no conditions are true, default_result is returned. If ELSE default_result is omitted, ELSE NULL is assumed (Listing 5.31 and Figure 5.31). ✔ Tips ■ You can use CASE in SELECT , WHERE , and ORDER BY clauses or anywhere an expres- sion is allowed. ■ When a result is returned, CASE may or may not evaluate the expressions in any remaining WHEN clauses, depending on the DBMS. For this reason, you should watch for undesirable side effects, such as the evaluation of any expression resulting in a division-by-zero error. continues on next page 163 Operators and Functions Evaluating Conditional Values with CASE Listing 5.31 List the books categorized by different sales ranges, sorted by ascending sales. See Figure 5.31 for the result. SELECT title_id, CASE WHEN sales IS NULL THEN 'Unknown' WHEN sales <= 1000 THEN 'Not more than 1,000' WHEN sales <= 10000 THEN 'Between 1,001 and 10,000' WHEN sales <= 100000 THEN 'Between 10,001 and 100,000' WHEN sales <= 1000000 THEN 'Between 100,001 and 1,000,000' ELSE 'Over 1,000,000' END AS "Sales category" FROM titles ORDER BY sales ASC; Listing title_id Sales category T10 Unknown T01 Not more than 1,000 T08 Between 1,001 and 10,000 T09 Between 1,001 and 10,000 T02 Between 1,001 and 10,000 T13 Between 10,001 and 100,000 T06 Between 10,001 and 100,000 T04 Between 10,001 and 100,000 T03 Between 10,001 and 100,000 T11 Between 10,001 and 100,000 T12 Between 100,001 and 1,000,000 T05 Between 100,001 and 1,000,000 T07 Over 1,000,000 Figure 5.31 Result of Listing 5.31. ■ This CASE expression can help you pre- vent division-by-zero errors: CASE WHEN n <> 0 THEN expr/n ELSE NULL END ■ You can use CASE to omit identical func- tion calls. WHERE some_function(col1) = 10 OR some_function(col1) = 20 is equivalent to WHERE 1 = CASE some_function(col1) WHEN 10 THEN 1 WHEN 20 THEN 1 END Some DBMS optimizers will run the CASE form faster. ■ The simple CASE expression is just short- hand for this searched CASE expression: CASE WHEN comparison_value = value1 THEN result1 WHEN comparison_value = value2 THEN result2 WHEN comparison_value = valueN THEN resultN [ELSE default_result] END ■ Microsoft Access doesn’t support CASE ; instead, use the function Switch(condition1, result1, condition2, result2, ) . To run Listings 5.30 and 5.31, change the CASE expressions to (Listing 5.30): Switch( ➝ type IS NULL, NULL, ➝ type = ‘history’, price * 1.10, ➝ type = ‘psychology’, price *1.20, ➝ type IN (‘biography’, ➝ ’children’, ‘computer’), price) and (Listing 5.31): Switch( ➝ sales IS NULL, ➝ ’Unknown’, ➝ sales <= 1000, ➝ ’Not more than 1,000’, ➝ sales <= 10000, ➝ ’Between 1,001 and 10,000’, ➝ sales <= 100000, ➝ ’Between 10,001 and 100,000’, ➝ sales <= 1000000, ➝ ’Between 100,001 and 1,000,000’, ➝ sales > 1000000, ➝ ’Over 1,000,000’) Oracle 9i and later will run Listings 5.30 and 5.31. To run Listing 5.30 in Oracle 8i, translate the simple CASE expression to a searched CASE expression, or use the function DECODE(comparison_value, value1, result1, value2, result2, , default_result) : DECODE(type, ➝ NULL, NULL, ➝ ’history’, price * 1.10, ➝ ’psychology’, price * 1.20, ➝ price) In older PostgreSQL versions, convert the floating-point numbers in Listing 5.30 to DECIMAL ; see “Converting Data Types with CAST() ” earlier in this chapter. To run Listing 5.30, change new-price calcula- tions in the CASE expression to: price * CAST((1.10) AS DECIMAL) price * CAST((1.20) AS DECIMAL) 164 Chapter 5 Evaluating Conditional Values with CASE Checking for Nulls with COALESCE() The function COALESCE() returns the first non-null expression among its arguments. COALESCE() often is used to display a specif- ic value instead of a null in a result, which is helpful if your users find nulls confusing. COALESCE() is just shorthand for a common form of the searched CASE expression. COALESCE(expr1, expr2, expr3) is equivalent to: CASE WHEN expr1 IS NOT NULL THEN expr1 WHEN expr2 IS NOT NULL THEN expr2 ELSE expr3 END To return the first non-null value: ◆ Type: COALESCE(expr1, expr2, ) expr1, expr2, , represent one or more comma-separated expressions. All expressions must be of the same type or must be implicitly convertible to the same type. Each expression is evaluated in order (left to right) until one evaluates to non-null and is returned. If all the expressions are null, COALESCE() returns null (Listing 5.32 and Figure 5.32) . ✔ Tips ■ You can use COALESCE() in SELECT , WHERE , and ORDER BY clauses or anywhere an expression is allowed. ■ Be aware that you can get a null from a column that doesn’t allow nulls; see Figure 3.3 in Chapter 3, for example. ■ Microsoft Access doesn’t support COALESCE() ; instead, use the function Switch() . To run Listing 5.32, change the COALESCE() expression to: Switch(state IS NOT NULL, state, ➝ state IS NULL, ‘N/A’) Oracle 9i and later will run Listing 5.32. Oracle 8i doesn’t support COALESCE() ; instead, use the function NVL(expr1, expr2) . NVL() takes only two expressions; use CASE for three or more expressions. To run Listing 5.32 in Oracle 8i, change the COALESCE() expression to: NVL(state, ‘N/A’) 165 Operators and Functions Checking for Nulls with COALESCE() Listing 5.32 List the publishers’ locations. If the state is null, print N/A. See Figure 5.32 for the result. SELECT pub_id, city, COALESCE(state, 'N/A') AS "state", country FROM publishers; Listing pub_id city state country P01 New York NY USA P02 San Francisco CA USA P03 Hamburg N/A Germany P04 Berkeley CA USA Figure 5.32 Result of Listing 5.32. Comparing Expressions with NULLIF() The function NULLIF() compares two expressions and returns null if they are equal or the first expression otherwise. NULLIF() typically is used to convert a user- defined missing, unknown, or inapplicable value to null. Rather than use a null, some people prefer to represent a missing value with, say, the num- ber –1 or –99, or the string ‘N/A’, ‘Unknown’, or ‘Missing’. DBMSs have clear rules for operations that involve nulls, so it’s some- times desirable to convert user-defined missing values to nulls. If you want to calcu- late the average of the values in a column, for example, you’d get the wrong answer if you had –1 values intermingled with the real, non- missing values. Instead, you can use NULLIF() to convert the –1 values to nulls, which your DBMS will ignore during calculations. NULLIF() is just shorthand for a common form of the searched CASE expression. NULLIF(expr1, expr2) is equivalent to: CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END 166 Chapter 5 Comparing Expressions with NULLIF( ) Avoiding Division by Zero Suppose you want to calculate the male–female ratios for various school clubs, but you discover that the following query fails and issues a divide-by-zero error when it tries to calculate ratio for the Lord of the Rings Club, which has no women: SELECT club_id, males, females, males/females AS ratio FROM school_clubs; You can use NULLIF to avoid division by zero. Rewrite the query as: SELECT club_id, males, females, males/NULLIF(females,0) AS ratio FROM school_clubs; Any number divided by NULL gives NULL , and no error is generated. To return a null if two expressions are equivalent: ◆ Type: NULLIF(expr1, expr2) expr1 and expr2 are expressions. NULLIF() compares expr1 and expr2. If they are equal, the function returns null. If they’re unequal, the function returns expr1. You can’t specify the literal NULL for expr1 (Listing 5.33 and Figure 5.33). ✔ Tips ■ You can use NULLIF() in SELECT , WHERE , and ORDER BY clauses or anywhere an expression is allowed. ■ Microsoft Access doesn’t sup- port NULLIF() ; instead, use the expression IIf(expr1 = expr2, NULL, expr1) . To run Listing 5.33, change the NULLIF() expression to: IIf(contract = 0, NULL, contract) Oracle 9i and later will run Listing 5.33. Oracle 8i doesn’t support NULLIF() ; instead, use CASE . To run Listing 5.33 in Oracle 8i, change the NULLIF() expression to: CASE WHEN contract = 0 THEN NULL ELSE contract END 167 Operators and Functions Comparing Expressions with NULLIF( ) Listing 5.33 In the table titles , the column contract contains zero if no book contract exists. This query changes the value zero to null. Nonzero values aren’t affected. See Figure 5.33 for the result. SELECT title_id, contract, NULLIF(contract, 0) AS "Null contract" FROM titles; Listing title_id contract Null contract T01 1 1 T02 1 1 T03 1 1 T04 1 1 T05 1 1 T06 1 1 T07 1 1 T08 1 1 T09 1 1 T10 0 NULL T11 1 1 T12 1 1 T13 1 1 Figure 5.33 Result of Listing 5.33. This page intentionally left blank The preceding chapter described scalar functions, which operate on individual row values. This chapter introduces SQL’s aggre- gate functions, or set functions, which oper- ate on a group of values to produce a single, summarizing value. You apply an aggregate to a set of rows, which can be: ◆ All the rows in a table ◆ Only those rows specified by a WHERE clause ◆ Those rows created by a GROUP BY clause A GROUP BY clause, which groups rows, often is used with a HAVING clause, which filters groups. No matter how many rows the input set contains, an aggregate function returns a single statistic: a sum, minimum, or average, for example. The main difference between queries with and without aggregate functions is that nonaggre- gate queries process the rows one by one. Each row is processed independently and put into the result. ( ORDER BY and DISTINCT make the DBMS look at all the rows, but they’re essentially postprocessing operations.) Aggregate queries do something completely different: They take a table as a whole and construct new rows from it. 169 Summarizing and Grouping Data 6 Summarizing and Grouping Data . CONVERT() in Microsoft SQL Server and MySQL; TO_CHAR() , TO_DATE() , TO_TIMESTAMP() , and TO_NUMBER() in Oracle and PostgreSQL; and TO_CHAR() and TO_DATE() in DB2. Search your DBMS documentation for. CAST() expression to: CAST(sales AS CHAR(8)) ➝ || ‘ copies sold of ‘ ➝ || SUBSTR(title_name, 1, 20) In MySQL, use SIGNED instead of INTEGER for data_type, and use CONCAT() to concatenate strings. To. null: CAST(‘’ AS CHAR) returns null. See the DBMS Tip in “Nulls” in Chapter 3. In older PostgreSQL versions, to compare a value in a NUMERIC or DECIMAL column with a real (floating-point) number,

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

TỪ KHÓA LIÊN QUAN