从他的楼梯到T-SQL DML,Gregory Larsen涵盖了更多的高级方面的T-SQL语言,如子查询。

有时您需要编写一个可以根据另一个表达式的评估返回不同的TSQL表达式的单个TSQL语句。当您需要这种功能时,您可以使用CASE表达式或IIF函数来满足此要求。在本文中,我将回顾CASE和IIF语法,并向您展示CASE表达式和IIF函数的示例。

了解CASE表达
Transact-SQL CASE表达式允许您在TSQL代码中放置条件逻辑。此条件逻辑为您提供了一种在TSQL语句中放置不同代码块的方法,该语句可以根据条件逻辑的TRUE或FALSE评估来执行。您可以在单个CASE表达式中放置多个条件表达式。当CASE子句中有多个条件表达式时,第一个计算结果为TRUE的表达式将是由TSQL语句评估的代码块。为了更好地了解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
2017/10/31 14:42:56

图1:CASE表达式语法

通过查看图1中CASE表达式的两种不同格式,您可以看到每种格式如何提供不同的方法来标识确定CASE表达式结果的多个表达式之一。对于两种类型的CASE,对每个WHEN子句执行布尔测试。使用简单CASE表达式,布尔测试的左侧出现在CASE单词之后,称为“input_expression”,右侧的“WHEN”表示右侧,称为“when expression”。使用简单CASE表达式,“input_expression”和“when_expression”之间的运算符始终是相等运算符。而搜索到的CASE表达式,每个WHEN子句将包含一个“Boolean_expression”。这个“Boolean_expression”可以是一个带有单个运算符的简单布尔表达式,也可以是具有许多不同条件的复杂布尔表达式。另外,搜索到的CASE表达式可以使用完整的布尔运算符集。

无论使用哪种CASE格式,每个WHEN子句按其出现顺序进行比较。 CASE表达式的结果将基于评估为TRUE的第一个WHEN子句。如果没有WHEN子句求值为TRUE,则返回ELSE表达式。当ELSE子句被省略且WHEN子句的计算结果为TRUE时,将返回NULL值。

示例数据样本
为了有一个表来演示使用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);
2017/10/31 14:44:39

清单1:创建示例表MyOrder

使用简单的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;

清单2:使用ELSE表达式的简单CASE表达式

让我先谈一谈为什么这是一个简单的CASE表达。如果您查看清单2中的代码,您可以看到紧跟在CASE字之后,我指定了表达式“YEAR(OrderDT)”,然后我按照三个不同的WHEN表达式,每个具有不同的年份指定,从2014开始。因为我指定CASE和第一个WHEN关键字之间的表达式告诉SQL Server这是一个简单的CASE表达式。

当我简单的CASE表达式被评估时,它使用“YEAR(OrderDate)”值和不同的WHEN表达式之间的等号运算符(“=”)。因此,清单1中的代码将为OrderType列显示“Year 1”,其中OrderDT年值为“2014”,否则对于OrderDT年份为“2013”​​的行将显示“Year 2”,或者将为OrderDT年份为“2012”的行显示“Year 3”。如果OrderDT的年份与WHEN表达式不匹配,则ELSE条件将显示“Year 4 and beyond”。

当我运行清单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
2017/10/31 14:46:16
结果1:运行清单2时的结果

使用没有ELSE表达式的简单CASE表达式
让我运行清单3中的代码,它将显示一个Simple CASE表达式没有ELSE子句时会发生什么。

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;。
2017/10/31 14:48:58

清单3:没有ELSE子句的简单CASE表达式

清单3中的代码就像清单2中的代码,但没有ELSE子句。 当我运行清单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的年份不符合WHEN子句条件时,SQL Server将为该行的YearType值显示“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:搜索CASE表达式

如果您查看清单4中的代码,您可以看到WHEN子句直接在CASE子句之后,两个子句之间没有文本。这告诉SQL Server这是一个搜索的CASE表达式。还要注意每个WHEN子句后面的布尔表达式。正如你可以看到并不是所有这些布尔表达式都使用等号运算符,最后一个WHEN表达式使用小于(“<”)运算符。清单4中的CASE表达式在逻辑上与清单2中的CASE表达式相同。因此,当我运行清单4中的代码时,会产生与结果1所示相同的结果。

如果多个WHEN表达式求值为TRUE,则返回什么表达式?
在单个CASE表达式中可能会有不同WHEN表达式求值为TRUE的情况。当这种情况发生时,SQL Server将返回与第一个WHEN表达式关联的结果表达式,该WHEN表达式计算结果为true。因此,如果多个WHEN子句评估为TRUE,则WHEN子句的顺序将控制从CASE表达式返回的结果。

为了证明这一点,当OrderAmt在$ 200范围内时,我们使用CASE表达式显示“200美元订单”,当OrderAmt在$ 100范围内时,“100美元订单”,当OrderAmt小于$ 100时,“100美元订单”当OrderAmt不属于这些类别时,将该订单分类为“300美元及以上订单”。我们来看看清单5中的代码,以演示当尝试将订单分类到其中一个OrderAmt_Category值时,当多个WHEN表达式求值为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:多个WHEN表达式求值为TRUE的示例

当我运行清单5中的代码时,我得到Result 3中的输出。
2017/10/31 14:51:01

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中的结果,您可以看到每个订单都被报告为200或300及以上的订单,我们知道这是不正确的。 这是因为我仅使用少于(“<”)运算符来简单地对在CASE表达式中导致多个WHEN表达式求值为TRUE的Orders进行分类。 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;

清单6:与清单5类似的代码,但WHEN子句的顺序不同

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

通过查看结果4中的输出,您可以看到,通过更改WHEN表达式的顺序,我得到每个订单的正确结果。

嵌套CASE表达式
有时您可能需要进行其他测试,以使用CASE表达式进一步分类数据。 当这种情况发生时,您可以使用嵌套的CASE表达式。 清单7中的代码显示了嵌套CASE表达式以进一步分类MyOrder表中的订单的示例,以确定订单是否超过$ 200时是否使用Layaway值购买订单。

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表达式,以查看MyOrder表中的订单是否使用Layaway选项购买,只能在超过$ 200的购买上购买。 嵌套CASE表达式时请牢记SQL Server只允许最多10个嵌套级别。

其他可以使用CASE表达式的地方
到目前为止,我的所有示例都使用CASE表达式通过将CASE表达式放在TSQL SELECT语句的选择列表中来创建结果字符串。 您还可以在UPDATE,DELETE和SET语句中使用CASE表达式。 另外,CASE表达式可以与IN,WHERE,ORDER BY和HAVING子句一起使用。 在清单8中,我使用了表示WHERE子句的CASE。

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表中的“Year 1”行返回一个订单。为了实现这一点,我将在WHERE子句中放置与清单2中所使用的相同的CASE表达式。我使用CASE表达式作为WHERE条件的左侧部分,因此它将根据OrderDT列生成不同的“Year ...”字符串。然后我测试了从CASE表达式生成的字符串,以查看它是否等于值“Year 1”,当它是从MyOrder表返回的行。请记住,当有其他更好的方法,如使用YEAR功能选择给定年份的行时,不建议使用CASE表达式从日期列中选择日期。我只在这里说明如何在WHERE子句中使用CASE语句。

使用IIF功能快速切换CASE表达式
随着SQL Server 2012的推出,微软增加了IIF功能。 IIF函数可以被认为是CASE语句的快捷方式。在图2中,您可以找到IIF函数的语法。

IIF ( boolean_expression, true_value, false_value )

图2:IIF功能的语法

“Boolean_expression”是一个有效的布尔表达式,相当于TRUE或FALSE。 当布尔表达式等于TRUE值时,执行“true_value”表达式。 如果布尔表达式等于FALSE,则执行“false_value”。 就像CASE表达式一样,IIF函数可以嵌套多达10个级别。

使用IIF的例子
为了演示如何使用IIF函数来替换CASE表达式,我们来看看使用清单9中搜索到的CASE表达式的代码。

SELECT OrderAmt,
       CASE 
  WHEN OrderAmt > 200 THEN 'High $ Order'
  ELSE 'Low $ Order' END AS OrderType
FROM MyOrder;

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

清单9中的代码只有一个WHEN表达式,用于确定OrderAmt是高或低美元订单。 如果WHEN表达式“OrderAMT> 200”计算结果为TRUE,则OrderType值设置为“High $ Order”。 如果WHEN表达式计算为FALSE,则为OrderType值设置“Low $ Order”。

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

SELECT OrderAmt,  
  IIF(OrderAmt > 200,
 'High $ Order',
 'Low $ Order') AS OrderType
FROM MyOrder;
2017/10/31 14:55:12

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

通过查看清单10,您可以看到为什么IIF函数被认为是CASE表达式的简写版本。 CASE替换为“IIF(”字符串,“THEN”子句用逗号替换,“ELSE”子句用逗号替换,“END”替换为“)”。 当布尔表达式“OrderAmt> 200”为TRUE时,显示值“High $ Order”。 当布尔表达式“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中的代码相当于使用清单7中的嵌套CASE表达式的代码。

限制
与大多数TSQL功能一样,存在限制。以下是有关CASE和IIF结构的一些限制。

CASE表达限制:

•CASE表达式中最多只能有10个嵌套级别。
•CASE表达式不能用于控制TSQL语句的执行流程。
IIF功能限制:

•您只能拥有多达10级的嵌套IIF子句。
概要
CASE表达式和IIF函数允许您将表达式逻辑放在TSQL代码中,这将基于表达式的计算结果来更改代码的结果。通过使用IIF函数和CASE表达式支持的比较表达式,可以根据比较表达式的计算结果为TRUE还是FALSE,执行不同的代码块。 CASE表达式和IIF函数为您提供编程控制,以满足您可能没有的业务需求。

问题和答案
在本节中,您可以回答以下问题,了解如何使用CASE和IIF构造。

问题1:
CASE表达式有两种不同的语法变体:Simple和Searched。下面哪两个语句最好地描述了简单和搜索的CASE表达式(Pick 2)之间的区别。

a。简单CASE语法仅支持等式运算符,而Searched CASE语法支持多个运算符
b。简单CASE语法支持多个运算符,而Searched CASE语法仅支持等式运算符
c。简单CASE语法在WHEN子句之后指定了布尔表达式,而Searched CASE语法在CASE语句之后具有布尔表达式的左侧,WHEN子句后面的布尔表达式的右侧。
d。简单CASE语法在CASE语句之后具有布尔表达式的左侧,WHEN子句后面的布尔表达式的右侧,而Searched CASE表达式在WHEN子句之后具有其布尔表达式

问题2:
如果CASE表达式有多个WHEN子句评估为TRUE,执行THEN / ELSE子句?

执行评估为TRUE的最后一个WHEN子句的THEN表达式。
b。执行计算为TRUE的第一个WHEN子句的THEN表达式。
c。执行评估为TRUE的WHEN子句的所有THEN表达式。
执行d.THE ELSE表达式
问题3:
CASE表达式或IIF函数有多少嵌套级别?

A.8
B.10
C.16
草32
回答:
问题1:
答案是a和d。简单的CASE语句只能使用相等运算符,而Searched CASE表达式可以处理多个运算符以及复杂的布尔表达式。另外,简单CASE语法具有紧靠单词CASE之后的等式运算符的左手部分,并且等于WHEN之后的等式运算符的右手部分。搜索的CASE表达式必须在WHEN子句之后完成布尔运算(左手部分,运算符,右手部分)

问题2:
正确的答案是b。如果多个WHEN子句求值为TRUE,则SQL Server仅执行第一个WHEN子句的THEN部分,该WHEN子句的计算结果为TRUE。被评估为TRUE的任何其他WHEN子句的所有其他THEN子句将被跳过。
2017/10/31 14:57:31
我的小秘 2017/10/31 14:57:31

问题3:
正确的答案是b。 CASE表达式和IIF功能仅支持最多10个嵌套级别

楼梯T-SQL:超越基础6级:使用CASE表达式和IIF函数的更多相关文章

  1. t-sql的楼梯:超越基本级别6:使用案例表达式和IIF函数

    t-sql的楼梯:超越基本级别6:使用案例表达式和IIF函数 源自:Stairway to T-SQL: Beyond The Basics Level 6: Using the CASE Expre ...

  2. SQL基础教程(第2版)第6章 函数、谓词、CASE表达式:6-1 函数

    6-1 各种各样的函数 ● 函数的种类很多,无需全都记住,只需要记住具有代表性的函数就可以了,其他的可以在使用时再进行查询. ■函数的种类所谓函数,就是输入某一值得到相应输出结果的功能,输入值称为参数 ...

  3. [SQL] SQL 基础知识梳理(六)- 函数、谓词、CASE 表达式

    SQL 基础知识梳理(六)-  函数.谓词.CASE 表达式 目录 函数 谓词 CASE 表达式 一.函数 1.函数:输入某一值得到相应输出结果的功能,输入值称为“参数”,输出值称为“返回值”. 2. ...

  4. 神奇的 SQL 之 CASE表达式,妙用多多 !

    前言 历史考试选择题:黄花岗起义第一枪谁开的? A宋教仁 B孙中山 C黄兴 D徐锡麟,考生选C. 又看第二题:黄花岗起义第二枪谁开的? 考生傻了,就选了个B. 接着看第三题:黄花岗起义中,第三枪谁开的 ...

  5. 6 SQL 函数、谓词、CASE表达式

    6 函数.谓词.CASE表达式 6-1 各种各样的函数 /* 所谓函数,就是输入某一值得到相应输出结果的功能.输入值称为参数(parameter),输出值称为返回值. 函数大致可以分为以下几种 : 算 ...

  6. SQL——语法基础篇(上)

    用数据库的方式思考SQL是如何执行的 虽然 SQL 是声明式语言,我们可以像使用英语一样使用它,不过在 RDBMS(关系型数据库管理系统)中,SQL 的实现方式还是有差别的.今天我们就从数据库的角度来 ...

  7. 第十篇 SQL Server安全行级安全

    本篇文章是SQL Server安全系列的第十篇,详细内容请参考原文. 不像一些其他industrial-strength数据库服务,SQL Server缺乏一个内置保护个别数据记录的机制,称为行级安全 ...

  8. 【译】第十篇 SQL Server安全行级安全

    本篇文章是SQL Server安全系列的第十篇,详细内容请参考原文. 不像一些其他industrial-strength数据库服务,SQL Server缺乏一个内置保护个别数据记录的机制,称为行级安全 ...

  9. SQL夯实基础(九)MySQL联接查询算法

    书接上文<SQL夯实基础(八):联接运算符算法归类>. 这里先解释下EXPLAIN 结果中,第一行出现的表就是驱动表(Important!). 对驱动表可以直接排序,对非驱动表(的字段排序 ...

随机推荐

  1. String类的一些常见的获取方法(5)

     String s = "aasfasfdtgsrast"; 1: int a = s.length() //返回字符串的长度 2: char s1 = charAt(int in ...

  2. OpenStack Ocata 超详细搭建文档

    前言 搭建前必须看我本文档搭建的是分布式O版openstack(controller+ N compute + 1 cinder)的文档.openstack版本为Ocata.搭建的时候,请严格按照文档 ...

  3. linux环境下根据文件的某一列进行去重

    momo@ubuntu:~/user/txt$ cat test.txt1 chen nihao2 chen hello3 li nimenhao4 he dajiahao5 li nimenhaom ...

  4. Https系列之三:让服务器同时支持http、https,基于spring boot

    Https系列会在下面几篇文章中分别作介绍: 一:https的简单介绍及SSL证书的生成二:https的SSL证书在服务器端的部署,基于tomcat,spring boot三:让服务器同时支持http ...

  5. 使用 Dawn 构建 React 项目

    开发一个 React 项目,通常避免不了要去配置 Webpack 和 babel 之类,以支持 commonjs 或 es 模块及各种 es 新语法,及及进行 jsx 语法的转义.当然也可以用 cre ...

  6. .NET第四章总结

    .NET第四章简单总结 1.简单的获取文件路径:                    2.回车跳转控件焦点    3.*************无标题窗体拖动!!************* 1): ...

  7. python之路第五篇之模块和加密算法(进阶篇:续)

    模块 Python中,如果要引用一些内置的函数,该怎么处理呢?在Python中有一个概念叫做模块(module) 简单地说,模块就是一个保存了Python代码的文件. 模块分类: 1)内置模块 2)自 ...

  8. 简单Elixir游戏服设计-创建玩家模型

    删除model.ex 创建玩家模型 player.ex, 简单化,只有唯一标识,昵称,金币,够用了. 选择 map 代表数据,是为了扩展数据结构,方便增加功能.struct也是可以的. add_num ...

  9. FPGA IN 金融领域

    何为金融: 金融指货币的发行.流通和回笼,贷款的发放和收回,存款的存入和提取,汇兑的往来等经济活动.金融(FIN)就是对现有资源进行重新整合之后,实现价值和利润的等效流通. 金融主要包括银行.证券.基 ...

  10. HDU2048 HDU2049 组合数系列 错排

    HDU1465HDU2048HDU2049#include<cstdio> #include<cstdlib> #include<iostream> #includ ...