通往T-SQL的阶梯: 超越基本的6级:使用CASE表达式和IF函数

通往T-SQL的阶梯:

超越基本的6级:使用CASE表达式和IIF函数。

作者Gregory Larsen, 2016/04/20(第一期出版:2014/04/09)

系列

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

从他的楼梯到T-SQL DML,格雷戈里·拉森涵盖了T-SQL语言的更高级的方面,比如子查询。

有时需要编写一个TSQL语句,该语句可以根据另一个表达式的值返回不同的TSQL表达式。

当您需要这种功能时,您可以使用CASE表达式或IIF函数来满足这一需求。

在本文中,我将回顾这个案例和IIF语法,并向您展示CASE表达式和IIF函数的示例。

理解CASE表达式

Transact-SQL CASE表达式允许在TSQL代码中放置条件逻辑。

这个条件逻辑为您提供了一种方法,可以将不同的代码块放置在您的TSQL语句中,这些代码块可以根据条件逻辑的真实或错误的评估来执行。

您可以将多个条件表达式放在一个单独的CASE表达式中。

当您的CASE子句中有多个条件表达式时,计算为TRUE的第一个表达式将是由TSQL语句计算的代码块。

为了更好地理解CASE表达式的工作方式,我将回顾这个CASE表达式的语法,然后遍历一些不同的例子。

CASE表达式语法

CASE表达式有两种不同的格式:Simplesearch

每种类型的格式都略有不同,如图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表达式语法。

通过查看图1CASE表达式的两种不同格式,您可以看到每种格式提供了一种不同的方式来确定多个表达式中的一个,这些表达式决定了CASE表达式的结果。

对于这两种类型的情况,每个WHEN子句都执行一个布尔测试。

在简单的CASE表达式中,布尔测试的左手边出现在CASE单词后面,被称为“input_expression”,而布尔测试的右手边则是“WHEN”,被称为“WHEN expression”。

使用简单的CASE表达式,在“input_expression”和“when_expression”之间的操作符始终是相等的运算符。

而在搜索的CASE表达式中,每个WHEN子句将包含一个“Boolean_expression”。

这个Boolean_expression”可以是一个简单的布尔表达式,一个操作符,或者一个复杂的布尔表达式,有许多不同的条件。

此外,搜索的CASE表达式可以使用完整的布尔运算符集。

不管使用哪种情况格式,每个WHEN子句都按照它出现的顺序进行比较。

这个CASE表达式的结果将基于对TRUE进行计算的第一个WHEN子句。

如果没有WHEN子句计算为TRUE,则返回ELSE表达式。

ELSE子句被省略,当子句计算为TRUE时,则回空值。

样本数据的例子

为了有一个表来演示使用CASE表达式,我将使用清单1中的脚本创建一个名为MyOrder的示例表。

如果您愿意跟随我的示例并在您的SQL Server例上运行它们,您可以在您选择的数据库中创建此表。

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

清单1:创建示例表MyOrder

使用一个简单的CASE表达式和其他表达式。

为了演示简单的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;

清单2:ELSE表示的简单的CASE表达式。

让我先谈谈为什么这是一个简单的案例表达。

如果您回顾一下清单2中的代码,您可以看到,在单词CASE之后,我指定了表达式“YEAR(OrderDT)”,然后我遵循了3个不同的表达式,每个表达式都指定了不同的年份,从2014开始。

因为我在CASE和第一个关键字之间指定了这个表达式,这告诉SQL Server这是一个简单的CASE表达式。

当我的简单的CASE表达式被求值时,它使用“YEAR(OrderDate)”值和不同的表达式之间的相等运算符(=)

因此,清单1中的代码将显示为YearType列“1年”行OrderDT年值“2014,或将显示“2年”行OrderDT一年的将显示“2013”或者“三年级”行OrderDT年的“2012”。

如果OrderDT的年份不匹配任何表达式,那么ELSE条件将显示“year 4beyond”。

当我运行清单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

结果1:运行清单2时的结果。

使用不带其他表达式的简单事例表达式

运行清单3中的代码, 它将显示当一个简单的事例表达式没有其他子句时会发生什么。

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;

清单 3: 没有其他子句的简单事例表达式

清单3中的代码就像清单2中的代码, 但没有其他子句。运行清单3中的代码时, 它会产生结果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

结果 2: 运行清单3时的结果

通过查看结果2中的输出, 您可以看到当MyOrder表中的OrderDT的年份不符合任何 where 子句条件时, SQL server 将为该行的 YearType 值显示 "NULL"

使用搜索的事例表达式

在简单的事例表达式中, 根据相等运算符计算表达式的时间。使用搜索的事例表达式, 可以用其他运算符, 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: 搜索的事例表达式

如果您查看清单4中的代码, 您可以看到, 当子句在两个子句之间没有文本的情况下, 则会直接遵循 If 语句。这将告诉 SQL server 这是一个搜索的事例表达式。还要注意每个子句后的布尔表达式。正如您所看到的, 并非所有这些布尔表达式都使用相等运算符, 最后一个当表达式使用小于 ("<") 运算符时。清单4中的事例表达式在逻辑上与清单2中的事例表达式相同。因此, 当我运行清单4中的代码时, 它会产生与结果1中所示相同的结果。

当表达式计算为 TRUE 时, 返回什么表达式?

在单个事例表达式中, 当表达式计算为 TRUE , 可能会出现不同的情况。发生这种情况时, SQL server 将返回与第一个计算结果为 true 的表达式关联的效果表达式。因此, 当子句计算为 TRUE , 子句的顺序将控制从事例表达式返回的结果。

为了演示这一点, 让我们使用 CASE 表达式显示 "200 美元订单", OrderAmt位于 $ 200 范围内时, "100 美元订单" OrderAmt位于 $ 100 范围内, "< 100 美元订单"OrderAmt小于 $ 100 OrderAmt不属于任何这些类别, 然后将订单归类为"300 美元和高于顺序"。让我们回顾一下清单5中的代码, 以演示当试图将订单归类为这些OrderAmt_Category值之一时, 当表达式计算为 TRUE , 会发生什么情况。

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: 当表达式计算为 TRUE 时的多个示例

当我运行清单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: 运行清单5时的结果

通过查看结果3中的结果, 您可以看到每种订单都报告为200300以上的顺序, 我们知道这是不正确的。之所以发生这种情况, 是因为我只使用小于 ("<") 运算符来简单对在我的事例表达式中计算为 TRUE 时导致多个表达式的顺序进行分类。当子句的排序不允许返回正确的表达式时。

通过重新订购我的时间子句, 我可以得到我想要的结果。清单6中的代码与清单5相同, 但我重新订购了何时子句以正确地对我的订单进行分类。

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;

 

 

 

原文

The code in Listing 3 is just like code in Listing 2 but without an ELSE clause.

 

嵌套IIF函数的示例

嵌套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中的代码相当于清单7中使用嵌套案例表达式的代码。限制与大多数TSQL功能一样,也存在限制。下面是一些关于案例和IIF构造的限制。案例表达的限制:在情况表达式中,只能有最多10个层次的嵌套。

Case表达式不能用于控制TSQL语句的执行流程。IIF职能限制:你只能有多达10个层次的嵌套IIF条款。摘要CASE表达式和IIF函数允许您将表达式逻辑放置在TSQL代码中,这将根据表达式的计算结果更改代码的结果。通过使用IIF函数支持的比较表达式和CASE表达式,可以根据比较表达式的计算结果为true还是false来执行不同的代码块。CASE表达式和IIF函数为您提供编程控制,以满足您可能没有的业务需求。问题答案在本节中,您可以通过回答以下问题来回顾如何使用案例和IIF构造来理解。

问题1:
大小写表达式有两种不同的语法变体:简单和搜索。
下面的两个语句最清楚地描述了一个简单的和被搜索的实例表达式之间的差异(Pick2)。
a.简单的案例语法仅支持相等运算符,而搜索到的案例语法支持多个运算符
b.简单的案例语法支持多个运算符,而搜索到的案例语法仅支持相等运算符
c.简单的实例语法具有在WHEN子句后指定的布尔表达式,而搜索的案例语法在Case语句之后具有布尔表达式的左侧,而在WHEN子句之后的布尔表达式的右侧。
d.简单的实例语法在CASE语句后面的布尔表达式的左侧和WHEN子句后布尔表达式的右侧,而搜索到的CASE表达式在WHEN子句后具有其布尔表达式
问题2:

如果CASE表达式有多个计算为true的WHERE子句,那么执行哪个/OSE子句?a.执行计算为true的最后一个WHERE子句的然后表达式。

b.执行计算为true的第一个WHERE子句的然后表达式。

c.然后执行计算为true的WHERE子句的所有表达式。

d.执行Other表达式。

问题3:

一个案例表达式或IIF函数可以有多少嵌套级别?

答案:

问题1:

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

问题2:

正确的答案是b。如果多个WHERE子句的计算结果为true,则SQL Server只执行第一个WILE子句中计算为true的RIT部分。当计算为true的子句被跳过时,所有其他的子句都会被跳过。

问题3:

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值