Homework Translation for Week 8 of the Big Four

series

This article is part of the Ladder series: The T-SQL Ladder: Beyond the Basics

From his ladder to T-SQL DML, Gregory Larson covers more advanced aspects of the T-SQL language, such as subqueries.

Sometimes it is necessary to write a TSQL statement that can return a different TSQL expression based on the value of another expression. When you need this kind of functionality, you can use CASE expressions or IIF functions to meet this need. In this article, I'm going to review this case and IIF syntax, and show you examples of CASE expressions and IIF functions.

understand the expression of the case

Transact-SQL CASE expressions allow conditional logic to be placed in TSQL code. This conditional logic gives you a way to place different blocks of code in your TSQL statements that can be executed depending on the true or false evaluation of the conditional logic. You can put multiple conditional expressions in a single CASE expression. When you have multiple conditional expressions in your CASE clause, the first expression that evaluates to TRUE will be the block of code evaluated by the TSQL statement. To better understand how CASE expressions work, I'm going to review the syntax of this CASE expression and then go through some different examples.

case expression syntax

CASE expressions come in two different formats: Simple and search. Each type has a slightly different format, as shown in Figure 1.

Simple CASE expression:

 

CASE input_expression

     WHEN when_expression THEN result_expression [ ...n ]

     [ ELSE else_result_expression ]

END

 

Searched CASE expression:

 

CASE

     WHEN Boolean_expression THEN result_expression [ ...n ]

     [ ELSE else_result_expression ]

END

Figure 1: Case expression syntax

By looking at the two different formats of the CASE expression in Figure 1, you can see that each format provides a different way to determine one of the multiple expressions that determine the result of the CASE expression. For both types of cases, each WHEN clause performs a boolean test. In a simple CASE expression, the left-hand side of the Boolean test appears after the CASE word and is called "input_expression", while the right-hand side of the Boolean test is "WHEN" and is called the "WHEN expression". With simple CASE expressions, the operators between "input_expression" and "when_expression" are always equality operators. And in the searched CASE expression, each WHEN clause will contain a "Boolean_expression". This "Boolean_expression" can be a simple boolean expression, an operator, or a complex boolean expression with many different conditions. In addition, the searched CASE expression can use the full set of Boolean operators.

Regardless of which case format is used, each WHEN clause is compared in the order in which it appears. The result of this CASE expression will be based on the first WHEN clause that evaluates to TRUE. If no WHEN clause evaluates to TRUE, the ELSE expression is returned. Null is returned when the ELSE clause is omitted and the clause evaluates to TRUE.

example of sample data

To have a table to demonstrate the use of CASE expressions, I'll use the script in Listing 1 to create a sample table called MyOrder. If you'd like to follow along with my examples and run them on your SQL Server instance, you can create this table in a database of your choice.

CREATE TABLE MyOrder (

ID int identity,

OrderDT date,

OrderAmt decimal(10,2),

Layaway char(1));

INSERT into MyOrder VALUES

('12-11-2012', 10.59,NULL),

('10-11-2012', 200.45,'Y'),

('02-17-2014', 8.65,NULL),

('01-01-2014', 75.38,NULL),

('07-10-2013', 123.54,NULL),

('08-23-2009', 99.99,NULL),

('10-08-2013', 350.17,'N'),

('04-05-2010', 180.76,NULL),

('03-27-2011', 1.49, NULL);

Listing 1: Creating the example table MyOrder

Use a simple CASE expression and other expressions

To demonstrate how the simple CASE expression format works, let me run the code in Listing 2.

SELECT YEAR(OrderDT) AS OrderYear,

       CASE YEAR(OrderDT)

                   WHEN 2014 THEN 'Year 1'

                   WHEN 2013 THEN 'Year 2'

                   WHEN 2012 THEN 'Year 3'

                   ELSE 'Year 4 and beyond' END AS YearType

FROM MyOrder;

Listing 2: Simple CASE expression expressed in ELSE

Let me first talk about why this is a simple case expression. If you look back at the code in Listing 2, you can see that after the word CASE, I specified the expression "YEAR(OrderDT)", and then I followed 3 different expressions, each specifying Different years, starting from 2014. Because I specified this expression between CASE and the first keyword, which tells SQL Server that this is a simple CASE expression.

When my simple CASE expression is evaluated, it uses the "YEAR(OrderDate)" value and the equality operator ("=") between the different expressions. Therefore, the code in Listing 1 would display the YearType column as the "1 year" row for the OrderDT year value "2014", or the "2 year" row for the OrderDT year would display the "2013" or the "3rd year" row for the OrderDT year "2012". If OrderDT's year does not match any expression, then the ELSE condition will display "year 4 and beyond".

When I run the code in Listing 2, I get the output in Result 1.

OrderYear YearType

----------- -----------------

2012        Year 3

2012        Year 3

2014        Year 1

2014        Year 1

2013        Year 2

2009        Year 4 and beyond

2013        Year 2

2010        Year 4 and beyond

2011        Year 4 and beyond

Result 1: Result when running Listing 2

Use a simple CASE statement with no other expressions

Let me run the code in Listing 3 and it will display a simple CASE expression with no ELSE clause.

SELECT YEAR(OrderDT) AS OrderYear,

       CASE YEAR(OrderDT)

                WHEN 2014 THEN 'Year 1'

                WHEN 2013 THEN 'Year 2'

                WHEN 2012 THEN 'Year 3' END AS YearType

FROM MyOrder;

Listing 3: Simple CASE expression without ELSE clause

The code in Listing 3 is similar to the code in Listing 2, but without the other clauses. When I run the code in Listing 3, it produces the results shown in Result 2.

OrderYear YearType

----------- --------

2012        Year 3

2012        Year 3

2014        Year 1

2014        Year 1

2013        Year 2

2009        NULL

2013        Year 2

2010        NULL

2011        NULL

Result 2: Result when running Listing 3

By examining the output in result 2, you can see that when the OrderDT year in the MyOrder table does not meet any of the when clause conditions, SQL Server displays the row with a YearType value of "NULL".

Case expression using search

In the simple case, expressions are evaluated based on equality operators. With searchable CASE expressions, we can use other operators, and the CASE expression syntax is slightly different. To demonstrate this, let's look at the code in Listing 4.

SELECT YEAR(OrderDT) AS OrderYear,

       CASE

                WHEN YEAR(OrderDT) = 2014 THEN 'Year 1'

                WHEN YEAR(OrderDT) = 2013 THEN 'Year 2'

                WHEN YEAR(OrderDT) = 2012 THEN 'Year 3'

                WHEN YEAR(OrderDT) < 2012 THEN 'Year 4 and beyond'

                       END AS YearType

FROM MyOrder;

Listing 4: CASE expression for search

If you look at the code in Listing 4, you can see that after the CASE clause, with no text between the two clauses, the WHEN clause follows directly. This tells SQL Server that this CASE expression can be searched. Also note the boolean expressions that follow each WHEN clause. As we can see, not all boolean expressions use the equality operator, the last expression uses the less than ("<") operator. The CASE expression in Listing 4 is logically the same as the CASE expression in Listing 2. So when I run the code in Listing 4, it produces the same results as in Result 1.

What is the returned expression when the expression evaluates to TRUE?

Different situations may arise when an expression evaluates to TRUE in a single expression. When this happens, SQL Server returns the resulting expression associated with the first expression that evaluates to true. Therefore, when more than one clause in a clause evaluates to TRUE, the order of the clauses will control the results you return from the CASE expression.

We use to display "$200 order" when an OrderAmt is in the $200 range, "$100 order" when an OrderAmt is in the $100 range and "<$100 order" when an OrderAmt is less than $100 when an OrderAmt does not fall into any of these The categories are sorted in the "Order Above $300". Let's review the code in Listing 5 to see what happens when multiple expressions evaluate to TRUE when trying to classify an order into one of these OrderAmt_Category values.

SELECT OrderAmt,

       CASE

                WHEN OrderAmt < 300 THEN '200 Dollar Order'

                WHEN OrderAmt < 200 THEN '100 Dollar Order'

                WHEN OrderAmt < 100 THEN '< 100 Dollar Order'

                ELSE  '300 Dollar and above Order'

                    END AS OrderAmt_Category

FROM MyOrder;

Listing 6: Similar code to Listing 5, but in a different order of clauses

When I run the code in Listing 5, I get the output in result 4.

OrderAmt OrderAmt_Category

--------------------------------------- --------------------------

10.59                                   < 100 Dollar Order

200.45                                  200 Dollar Order

8.65                                    < 100 Dollar Order

75.38                                   < 100 Dollar Order

123.54                                  100 Dollar Order

99.99                                   < 100 Dollar Order

350.17                                  300 Dollar and above Order

180.76                                  100 Dollar Order

1.49                                    < 100 Dollar Order

Result 4: Result when running Listing 6

By examining the output in result 4, we can see that by changing the order of the expressions, we get the correct result for each order.

nested expression

Sometimes, we may need to do some additional tests in order to further classify the data using CASE expressions. When this happens, nested CASE expressions can be used. The code in Listing 7 shows an example of a nested case expression to further classify the orders in the MyOrder table to determine if the order was purchased using the Layaway value when the order was over $200.

SELECT OrderAmt,

       CASE

                WHEN OrderAmt < 100 THEN '< 100 Dollar Order'

                WHEN OrderAmt < 200 THEN '100 Dollar Order'

                WHEN OrderAmt < 300 THEN

                      CASE

                            WHEN Layaway = 'N'

                                THEN '200 Dollar Order without Layaway'

                                ELSE '200 Dollar Order with Layaway' END

                ELSE 

                      CASE

                            WHEN Layaway = 'N'

                                THEN '300 Dollar Order without Layaway'

                                ELSE '300 Dollar Order with Layaway' END

                    END AS OrderAmt_Category

FROM MyOrder;

Listing 7: Nested CASE statements

The code in Listing 7 is similar to the code in Listing 6. The only difference is that I added an additional CASE expression to see if the order in the MyOrder table was purchased with the Layaway option, which only allows purchases over $200. Remember that when you nest CASE expressions SQL Server only allows you to have up to 10 levels of nesting.

Other places where CASE expressions can be used

All my examples so far have used CASE expressions to create a resulting string, placing the CASE expression in the select list of a TSQL select statement. You can also use CASE expressions in UPDATE, DELETE, and SET statements. Additionally, CASE expressions can be used in conjunction with the in, WHERE, ORDER BY, and HAVING clauses. In Listing 8, I use a CASE that represents the WHERE clause.

SELECT *

FROM MyOrder

WHERE CASE YEAR(OrderDT)

              WHEN 2014 THEN 'Year 1'

              WHEN 2013 THEN 'Year 2'

              WHEN 2012 THEN 'Year 3'

              ELSE 'Year 4 and beyond' END = 'Year 1';

Listing 8: Using the CASE expression in the WHERE clause

In Listing 8, I only want to return the rows in "Year 1" from the MyOrder table. To achieve this, I put the same CASE expression in Listing 2 used in the WHERE clause. I use a CASE expression to put on the left side of the WHERE condition, so it will produce a different "Year..." string based on the OrderDT column. I then tested the string generated from the CASE expression to see if it was equal to the value of "Year 1" which, when it was a row, would be returned from the MyOrder table. Keep in mind that I don't recommend using a CASE expression to select a date from a date column, use something like "Year 1", if there is another better way, like using the Year function to select rows for a given year. I just demonstrated here how to use the CASE statement in the WHERE clause.

Shorten case expressions using the IIF function

With the introduction of SQL Server 2012, Microsoft added IIF functionality. The IIF function can be seen as a shortcut for the CASE statement. In Figure 2, the syntax of the IIF function can be found.

IIF ( boolean_expression, true_value, false_value )

Figure 2: Syntax of the IIF function

"Boolean_expression" is a valid Boolean expression equal to TRUE or FALSE. The "true_value" expression is executed when the boolean expression equals the TRUE value. If the boolean expression is equal to FALSE, "pseudo-value" is executed. Just like CASE expressions, IIF functions can be nested up to 10 levels.

Example using IIF

To demonstrate how to use the IIF function to replace a CASE expression, let's review the code in Listing 9 that uses the CASE expression used to search.

SELECT OrderAmt,

       CASE

                WHEN OrderAmt > 200 THEN 'High $ Order'

                ELSE 'Low $ Order' END AS OrderType

FROM MyOrder;

Listing 9: Example of a simple expression

 

The code in Listing 9 has only one expression that determines whether OrderAmt is a high or low dollar order. If the expression "OrderAMT > 200" evaluates to TRUE, then the OrderType value will be set to "High$Order". Set "low $Order" for the OrderType value if when the expression evaluates to FALSE.

 

The rewritten code that uses the IIF function instead of the CASE expression can be found in Listing 10.

SELECT OrderAmt, 

         IIF(OrderAmt > 200,

               'High $ Order',

               'Low $ Order') AS OrderType

FROM MyOrder;

Listing 10: Example using the IIF function

 

By looking at Listing 10, you can see why the IIF function is considered a shorthand version of the CASE expression. The word CASE is replaced with the "IIF(" string, the "THEN" clause is replaced with a comma, the "ELSE" clause is replaced with a comma, and "END" is replaced with ")". When the boolean expression "OrderAmt > 200" is TRUE, the value of "High$Order" will be displayed. "Low $Order" will be displayed when the boolean expression "OrderAmt > 200" evaluates to FALSE. If you run the code in Listings 9 and 10, you will see that they both output the exact same result.

 

Example nested IIF function.

Just like SQL Server allows you to nest IIF functions. In Listing 11 is an example of a nested IIF function.

SELECT OrderAmt,

       IIF (OrderAmt < 100,

               '< 100 Dollar Order',

               (IIF (OrderAmt < 200,

                       '100 Dollar Order',

                     (IIF (OrderAmt < 300,

                            (IIF (Layaway = 'N',

                                        '200 Dollar Order without Layaway',

                                        '200 Dollar Order with Layaway'

                                        )

                                   ),

                                   (IIF (Layaway = 'N',

                                         '300 Dollar Order without Layaway',

                                         '300 Dollar Order with Layaway'

                                        )

                               )

                                  )

                             )

                        )

              )

              ) AS OrderAmt_Category

FROM MyOrder;

Listing 11: Nested example of IIF function.

 

In this example, you can see that I have used the IIF function several times. Each additional one is used in the "true value" or "false value" of the IIF function. The code in Listing 11 is equivalent to using the nested CASE expression in Listing 7.

 

limit

As with most TSQL features, there are some limitations. Below are some restrictions on case and IIF construction.

 

Limitations of case expression:

 

You can only have up to 10 levels of nesting in a CASE expression.

CASE expressions cannot be used to control the flow of execution of TSQL statements.

IIF functional limitations:

 

You can only have up to 10 levels of nesting of IIF clauses.

Summarize

CASE expressions and IIF functions allow you to place expression logic in TSQL code, which will change the result of the code based on how the expression evaluates. By using the comparison expressions supported by IIF functions and CASE expressions, you can execute with different code blocks depending on whether the comparison expression evaluates to true or false. Case expressions and IIF functions give you programmatic control for business needs you may not have.

 

question and answer

In this section, you can review how you understand the use of this case and the IIF structure by answering the following questions.

 

Question 1:

There are two different syntax variants of case expressions: simple and search. The following two statements best describe the difference between simple and searched CASE expressions (option 2).

 

The simple CASE syntax supports only equality operators, while the searched CASE syntax supports multiple operators.

The simple CASE syntax supports multiple operators, while the searched CASE syntax supports only equality operators.

Simple CASE syntax has its Boolean expression specified after the WHEN clause, while searched CASE syntax has the left side of the Boolean expression after the CASE statement and the right side of the Boolean expression after the WHEN clause.

Simple CASE syntax is on the left side of the Boolean expression following the CASE statement and on the right side of the Boolean expression following the WHEN clause, while the searched CASE expression has its Boolean expression after the WHEN clause.

Question 2:

If the CASE expression has multiple WHEN clauses that evaluate to TRUE, is the /ELSE clause executed?

 

The expression of the last clause that evaluates to TRUE is executed.

The expression of the first WHEN clause that evaluates to TRUE is then executed.

All expressions of clauses that evaluate to TRUE are executed.

other expressions are executed.

Question 3:

How many nesting levels can a CASE expression or IIF function have?

 

8

10

16

32

Answer:

Question 1:

The answers are a and d. A simple CASE statement can only use equality operators, while searched CASE expressions can handle multiple operators, as well as complex Boolean expressions. In addition, simple CASE syntax has the left part of the equality operator after the word CASE and the right part to the right of the equal sign after the word. The searched CASE expression must complete the Boolean operation (left-hand part, operator, right-hand part) after the WHEN clause.

 

Question 2:

The correct answer is b. If multiple WHEN clauses evaluate to TRUE, then SQL Server executes only the then part of the first WHEN clause. When a clause that evaluates to true is skipped, all other clauses are omitted.

 

Question 3:

The correct answer is b. CASE expressions and IIF functions only support up to 10 levels of nesting.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325010492&siteId=291194637