翻译7

Stairway to T-SQL: Beyond The Basics Level 6: Using the CASE Expression and IIF Function

这篇文章是阶梯系列的一部分:通往T-SQL的阶梯:超越基础

从他的通往T-SQL的阶梯之后,Gregory Larsen 覆盖了更多T-SQL语言的高级部分例如子查询。

有时候你需要编写单个T-SQL语句,该语句能基于另一个表达式的值返回不同的T-SQL表达式。当你需要这种功能时你可以用case表达式或IIF功能来满足这一需求。在这一篇文章中我将会回顾case和IIF语法并向你展示如何使用CASE和IIF的例子。

理解CASE表达式

Transact-SQL表达式允许你将条件逻辑放在你的T-SQL代码中。这个条件逻辑为你提供了一种放置不同代码片段进入你的T-SQL语句块的方法,这些语句可以条件逻辑TRUE或FALSE来评价。你可以在单一的CASE表达式中你可以放置多种表达条件。当你在你的CASE语句中有多种表达条件时,第一个评估为TRUE的代码块将从你的T-SQL语句中选择。为了更好的理解CASE表达式如何工作,我将会通过回顾CASE表达式的语法和一些不同例子。

CASE表达式的语法

CASE表达式有两种不同的板式:简单和搜索。在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

1. CASE表达式的语法

通过1中CASE表达式的两种不同的格式你可以看看每个格式如何提供一种不同的方法去识别多种表达式中的一种决定CASE表达式的结果。随着CASE的两种类型,对每个WHEN语句执行Boolean测试。用简单的例子表达布尔测试的左侧现实在单词之后并且称为“输入表达式”,而布尔测试的右后CASE单词称作“时表达式”。用简单的CASE表达式在“输入表达式”和“时表达式”之间总有相等的操作。反之在每个WHEN语句中搜索CASE表达式将会包含一个“布尔-表达式”。这个“布尔-表达式”可以是个简单的布尔表达式的操作,或者是由多种不同条件的复杂布尔测试。此外,搜索布尔表达式可以用布尔操作的全集。

不论用那种CASE板式,每个WHEN语句都有自己的出现顺序。CASE表达式的结果在WHEN语句为真值时将基于先。如果WHEN语句的值不为真,则以ELSE语句返回。当WHERE语句不存在并且WHEN的值不为真,结果将以空值返回。

简单的数据例子

为了有一个表来演示,我将使用CASE表达式1中的脚本穿件一个名为MyOrder的例子。如果你想要跟着我的例子,可以在你的数据库中创建这张表,并运行。

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);

  使用一个简单的CASE表达式和WHEN、ELSE表达式

为了展示简单的CASE表达式板式如何运行,让我运行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;

让我们首先讨论这个简单的CASE表达式。如果你回顾2中的代码你能看见在CASE后我指定了表达式“YEAR”,接着我接着三个不同的WHEN表达式都有各自不同的指定年,从2014开始。由于我指定了表达式在CASE和第一个WHEN之间,这指只是个简单的CASE表达式在SQL Server中。

当我的简单CASE表达式被求值时,它使用相等运算符=在年值和表达式之间的。因此1中的代码将显示Yeartype 列中的“YEAR1”在此行中OrderDT年的值为“2014”。或展示“YEAR2”行中YearDT年为“2013”,或者会展示“Year3”行中OrderDT年为“2012”。如果OrderDT的年不匹配任何一个当表达式时,ELSE条件将显示“年4及其以后”。当我运行2中的代码我将得到结果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

没有ELSE表达式使用一个简单的CASE表达式

让我运行3中的代码,它将会展示当一个简单色CASE语句没有WHERE语句是会发生什么。

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

通过回顾2的输出结果你可以看到OrderDT中在MyOrder年不满足任何WHEN从句系统SQL Server会显示“NULL”在相应的行中。

用一个搜索CASE表达式

在一个简单的CASE表达式中WHEN表达式会基于同等操作执行。随着搜索CASE表达式你可以用其他的操作,并且CASE表达式的语法有些许不同。为了证明这个让我们看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;

如果你查看4中的代码你能看到WHEN从句直接跟在WHERE从句后在没有正文额情况下。这个表明了SQL Server搜索一个CASE表达式。还要注意在每个

我很语句后的布尔表达式。正如你所看到的不是所有的布尔表达式使用同等的操作,上一个WHEN表达式用小于操作。在4中的CASE表达式基于与2中的相同的CASE表达式。因此当我运行这段代码时产生与1相同的结果。

什么表达式返回多个WHEN表达式为TRUE的值?

这可能有在单一的CASE表达式中存在不同的WHEN表达式值为TRUE的情况。当这种情况发生时,SQL Server将会返回结果表达式中德 第一个与求值为真的表达式相关联的表达式。因此WHEN语句的顺序将控制返回的结果从你的CASE表达式中,如果多个WHEN语句的值为TRUE。

为了演示这一点,让我们使用CASE表达式来显示“200美元定单”。当OrderAmt在200美元范围内时,OrderAmt是“100美元定单”。当它小于100美元定单则“<100美元定单”。当OrderAmt不在上述的这些范围内时定单“300美元或以上”。让我们回顾5中的代码演示。当多个WHEN表达式值为真时会发生什么,当侍者将订单分类为这些OrderAmt-Category之中的一个。

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;

当我执行5中的代码,我的到结果3中的输出

OrderAmt                                OrderAmt_Category

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

10.59                                   200 Dollar Order

200.45                                  200 Dollar Order

8.65                                    200 Dollar Order

75.38                                   200 Dollar Order

123.54                                  200 Dollar Order

99.99                                   200 Dollar Order

350.17                                  300 Dollar and above Order

180.76                                  200 Dollar Order

1.49                                    200 Dollar Order

通过回顾结果3中的结果,你可以看到每个定单都被报告为200或300和以上的顺序,我们知道这是不对的。这个发生的原因是我只使用了小于运算符。在我的CASE表达式中用多个WHEN表达式来排序。那么WHEN语句将不会按照正确的表达方式返回。

通过重新排序我单位WHEN语句,我能得到我想要的结果。6中的代码与5中的相同但是我重新排列的WHEN语句准确的按我的命令执行。

SELECT OrderAmt,

       CASE

  WHEN OrderAmt < 100 THEN '< 100 Dollar Order'

  WHEN OrderAmt < 200 THEN '100 Dollar Order'

  WHEN OrderAmt < 300 THEN '200 Dollar Order'

  ELSE  '300 Dollar and above Order'

      END AS OrderAmt_Category

FROM MyOrder;

但我运行5中的代码,我得到结果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

通过回顾结果4中的输出,你可以看到改变WHEN表达式的语句我的到每个命令准确的结果。

嵌套实例表达
有时,您可能需要进行额外的测试,以便使用CASE表达式进一步对数据进行分类。当发生这种情况时,可以使用嵌套的CASE表达式。清单7中的代码显示了嵌套CASE表达式以进一步分类My Order表中订单的示例,以确定订单是否在订单超过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;

清单7:嵌套Case语句

清单7中的代码类似于清单6中的代码。唯一的区别是添加了一个额外的CASE表达式,以查看my Order表中的订单是否是使用使用定金选项购买的,该选项只允许在超过200次的采购中购买。请记住,当您嵌套CASE表达式时,SQL Server只允许您有多达10个级别的嵌套。

可以使用案例表达式的其他地方

到目前为止,我的所有示例都使用case表达式创建结果字符串,方法是将case表达式放在T—SQL SELECT语句的SELECT列表中。还可以在UPDATE、DELETE和SET语句中使用CASE表达式。此外,案例表达式可以与IN一起使用。清单8中的WHERE、ORDERBY和WITH子句--我使用的是一个表示WHERE .

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';

清单8:在where子句中使用case表达式

在清单8中,我只想从MyOrder表中为“第一年”中的行返回一个订单。为了实现这一点,我在WHERE子句中放置了与清单2中使用的相同的CASE表达式。我使用case表达式作为WHERE条件的左侧部分,以便根据Order DT列生成不同的“年份...”字符串。然后,我测试从case表达式中生成的字符串,看看它是否等于值“年份1”,当它是行时,将从My Order表返回它。请记住,我不建议使用CASE表达式从日期列中选择日期,使用诸如“年份1”这样的圈套,因为有其他更好的方法,比如使用YEAR函数来选择给定年份的行。我在这里这样做只是为了演示如何在WHERE子句中使用CASE语句。

使用IIF函数的case表达式

表达式使用TIF函数引入SQLServer 2012,Microsoft添加了IIF函数。可以将IIF函数转换为图2中的case语句的快捷方式,您可以找到if函数的语法。

IIF ( boolean_expression, true_value, false_value )

图2:IIF函数的语法

IIF函数的语法--“布尔表达式”是一个有效的布尔表达式,等于true或false。当布尔表达式等于真值时,则执行“true_value”表达式。如果布尔表达式等于false,则执行“false_vaJue”。就像案例表达式一样,IIF函数可以嵌套到10个级别。

使用IIF函数的例子

为了演示如何使用IIF函数替换CASE表达式。让我们回顾一下在Listina 9中使用搜索过的案例表达式的代码 。

SELECT OrderAmt,

       CASE

  WHEN OrderAmt > 200 THEN 'High $ Order'

  ELSE 'Low $ Order' END AS OrderType

FROM MyOrder;

清单9:简单的案例表达式示例

清单9中的代码只有一个WHERE表达式,用于确定OrderAmtis是高还是低美元顺序。如果时间表达式“OrderAMT 200”计算为true,则OrderType值设置为“高阶”。如果WHERE表达式的计算结果为false,则为OrderType值设置“低阶”。

使用IIF函数而不是case表达式的重写代码可以在清单10中找到。

 

SELECT OrderAmt,  

  IIF(OrderAmt > 200,

 'High $ Order',

 'Low $ Order') AS OrderType

FROM MyOrder;

清单10:使用IIF函数的例子

通过查看清单10,您可以了解为什么IIF函数被认为是CASE表达式的速记版本。用“IIF”代替大小写(“String,”然后“else”子句替换为逗号,“end”改为“”)。当布尔表达式“OrderAmt 200”为真时,“高阶”的值就会被DiscreJayed。当布尔表达式‘OrderAmt 200’被计算为false时,就会显示“低阶”。如果您运行清单9和10中的代码,您将看到它们都产生完全相同的输出。

IIF函数嵌套的例子

就像case表达式Sql Server允许你嵌套IIF函数一样。清单11是嵌套IIF函数的一个例子。

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;

清单11:一个IIF函数嵌套的例子

在这个例子中,您可以看到我多次使用了IIF函数。每一个附加的值要么用于IIF函数的“真值”,要么用于“假值”。清单11中的代码等效于使用Listina 7中嵌套的CASE表达式的代码。

限制

与大多数TSQL功能一样,也有限制、大小写和IIF结构。

Case表达式的限制

·您只能有多达10个层次的嵌套。

·Case表达式不能用于控制TSQL语句F函数限制的执行流程。

·你只能有多达10个层次的iff条款嵌套。

总结

CASE表达式和IIF函数允许您将表达式逻辑放置在TSQL代码中,这将根据表达式的计算结果更改代码的结果。通过使用比较表达式u、IIF函数和CASE表达式,您可以让不同的代码块执行dpjPdirtgdoby,无论比较表达式是真还是假,CASE表达式和IIF函数为您提供编程控制,以满足您可能没有的业务需求。

问题和答案

在本节中,你可以通过回答以下问题来回顾你如何理解用这个案例和IIF构造。

问题1

 这个案例表达式有两个不同的语法变体:简单语法和搜索语法。下面哪两个语句最能描述简单的案例表达式和搜索的案例表达式之间的区别.(选两个)

A. 简单的实例语法只支持等式运算符,而搜索的案例语法支持多个运算符。

B. 简单的实例语法支持多个运算符,而搜索的实例语法仅支持相等运算符。

C. 简单的实例语法具有布尔表达式SPECF。在WHON子句之后的IED,而搜索的case语法在case语句之后有布尔表达式的左侧,以及WHON子句后面的布尔表达式的右侧。

D. 简单的case语法在布尔语句表达式的左边和后面的布尔表达式的右边有布尔表达式的左边,而被搜索的case Exchange在WHON子句后面有它的布尔表达式。

问题2

 如果案例表达式在评估为true的子句时具有多个。如果执行了“Else子句”,

A. 则执行评估为true的子句的最后一个表达式,

B. 然后执行评估为true的子句的表达式,

C. 然后执行评估为true的子句的表达式。

D. 还执行了其他的外推式,

问题3

一个案例表达式或IIF函数如何具有多少个嵌套级别?

A. 8

B. 10

C. 16

D. 32

回答

问题1:

正确的答案是a一个简单的CASE语句只能使用相等的操作符,而搜索的CASE表达式可以处理多个操作符以及复杂的布尔表达式。此外,简单的CASE语法在单词case后面有相等操作符的左手部分,在单词WHILE后面有相等操作符的右边部分。搜索的案例表达式必须在WHERE子句之后的右边完成布尔运算(左手部分、操作符、右手部分)。

问题2:

正确的答案是b多数位时从句求值为true,然后将第一个WHERE子句中的SQ部分计算为true。当计算为true的子句被跳过时,所有其他的子句都会被跳过。

问题3:

正确的答案是b,CASE表达式和IIF函数只支持最多10个嵌套。

本文是T-sql楼梯的一部分。

 

 

 

 




猜你喜欢

转载自blog.csdn.net/xtt_3170707038/article/details/80159459
今日推荐