SQL Server 中的 CASE 语句和嵌套 Case:T-SQL 示例

真实生活中的案例概述!

同样,在现实生活中,我们会根据不同条件的执行结果来执行不同的操作。

为了更详细地说明,请看下面的例子

  • 如果机票价格低于100美元,我将访问洛杉矶。
  • 如果机票价格在100美元到200美元之间,我将访问纽约
  • 如果机票价格在200美元到400美元之间,我将访问欧洲
  • 否则,我宁愿去附近的一个旅游景点。

让我们将上述示例中的条件和操作分别分类如下

条件 – 机票 执行的操作,仅当条件为
低于100美元 访问洛杉矶
100美元至200美元之间 访问纽约
200美元至400美元之间 访问欧洲
以上条件均不满足 附近的旅游景点

在上面的例子中,我们可以看到不同条件的执行结果会指导不同的操作。例如,访客仅在机票价格在100美元到200美元之间的条件下执行访问纽约的操作。

同样,MS SQL CASE语句也提供了根据不同条件的结果来执行不同 T-SQL 语句的能力。

SQL Server 中的 CASE 语句是什么?

SQL Server 中的 CASE 语句是 IF…ELSE 语句的扩展。与 IF…ELSE 不同,后者最多只允许一个条件,而 CASE 允许用户应用多个条件来执行 MS SQL 中的不同操作集。它会返回用户定义的条件所对应的赋值。

在接下来的章节中,让我们学习如何在 SQL 中使用 Case 及其概念。

MS SQL 中,CASE 有两种类型。

  1. 简单 CASE
  2. 搜索 CASE

简单 CASE

简单 Case 的语法

CASE <Case_Expression>
     WHEN Value_1 THEN Statement_1
     WHEN Value_2 THEN Statement_2
     .
     .
     WHEN Value_N THEN Statement_N
     [ELSE Statement_Else]   
END AS [ALIAS_NAME]

此处,

  • 参数 Case_Expression 表示我们将最终与之比较的表达式 Value_1, Value_2, …
  • 参数 Statement_1, Statement_2… 表示如果 Case_Expression = Value_1, Case_Expression = Value_2, … 等等,将要执行的语句。
  • 简而言之,条件是 Case_Expression = Value_N,而操作是在上述结果为真时执行 Statement_N。
  • ALIAS_NAME 是可选的,它是给 SQL Server CASE 语句结果的别名。当我们将在 SQL server select 子句中使用 Case 时,通常会用到它。

简单 Case 的规则

  • 简单 Case 只允许 Case_Expression 与 Value_1 到 Value_N 进行相等性检查。
  • Case_Expression 与 Value 的比较,按顺序从第一个值开始,即 Value_1。下面是执行方法
  • 如果 Case_Expression 等同于 Value_1,则会跳过后续的 WHEN…THEN 语句,CASE 执行将立即结束
  • 如果 Case_Expression 与 Value_1 不匹配,则 Case_Expression 将与 Value_2 进行比较以确定是否相等。此过程将继续,直到 Case_Expression 从 Value_1、Value_2… 的集合中找到匹配的等效值。
  • 如果没有匹配项,则控制转到 ELSE 语句,并将执行 Statement_Else。
  • ELSE 是可选的。
  • 如果不存在 ELSE 且 Case_Expression 与任何值都不匹配,则将显示 Null

下图说明了简单 Case 的执行流程。

Working of Simple Case Statement
简单 Case 语句的工作原理

示例

假设:假设我们有一个名为“Guru99”的表,其中包含两列和四行,如下所示

Simple Case  in SQL Server

我们将在后续示例中使用“Guru99”

查询 1:带有 NO ELSE 选项的简单 CASE

SELECT Tutorial_ID, Tutorial_name,
CASE Tutorial_name
	WHEN 'SQL' THEN 'SQL is developed by IBM'
	WHEN 'PL/SQL' THEN 'PL/SQL is developed by Oracle Corporation.'
	WHEN 'MS-SQL' THEN 'MS-SQL is developed by Microsoft Corporation.'
END AS Description
FROM Guru99

结果:下图解释了带有 NO ELSE 的简单 CASE 的执行流程。

Simple Case in SQL Server

查询 2:带有 ELSE 选项的简单 CASE。

SELECT Tutorial_ID, Tutorial_name,
CASE Tutorial_name
	WHEN 'SQL' THEN 'SQL is developed by IBM'
	WHEN 'PL/SQL' THEN 'PL/SQL is developed by Oracle Corporation.'
	WHEN 'MS-SQL' THEN 'MS-SQL is developed by Microsoft Corporation.'
	ELSE 'This is NO SQL language.'
END AS Description
FROM Guru99

结果:下图解释了带有 ELSE 的简单 CASE 的执行流程。

Simple Case in SQL Server

搜索 CASE

搜索 Case 的语法

CASE 
     WHEN <Boolean_Expression_1> THEN Statement_1
     WHEN <Boolean_Expression_2> THEN Statement_2
     .
     .
     WHEN <Boolean_Expression_N> THEN Statement_N
     [ELSE Statement_Else]   
END AS [ALIAS_NAME]

此处,

  • 参数 Boolean_Expression_1, … 表示将为真或假进行评估的表达式。
  • 参数 Statement_1, Statement_2… 表示如果其对应的 Boolean_Expression_1, Boolean_Expression_2 结果为真,将要执行的语句。
  • 简而言之,条件是 Boolean_Expression_1,…,而操作是在上述 boolean_Expression_1 为真时执行 Statement_N。
  • ALIAS_NAME 是可选的,它是给 CASE 语句结果的别名。当我们将在 select 子句中使用 CASE 时,通常会用到它。

搜索 Case 的规则

  • 与简单 case 不同,搜索 Case 不仅限于相等性检查,还允许布尔表达式。
  • 布尔表达式的评估顺序从第一个布尔表达式开始,即 Boolean_expression_1。下面是执行方法
    • 如果 Boolean_expression_1 为真,则会跳过后续的 WHEN…THEN 语句,CASE 执行将立即结束
    • 如果 Boolean_expression_1 为假,则会评估 Boolean_expression_2 以确定真条件。此评估布尔表达式的过程将继续,直到其中一个布尔表达式返回真。
    • 如果没有匹配项,则控制转到 ELSE 语句,并将执行 Statement_Else。
  • 与简单 Case 一样,搜索 Case 中的 ELSE 也是可选的。
  • 如果不存在 ELSE 且没有布尔表达式返回真,则显示 Null。

下图说明了搜索 Case 的执行流程。

Working of Searched Case Statement

搜索 Case 语句的工作原理

示例

查询 1:带有 NO ELSE 选项的搜索 CASE

SELECT Tutorial_ID, Tutorial_name,
CASE 
 	WHEN Tutorial_name = 'SQL' THEN 'SQL is developed by IBM'
	WHEN Tutorial_name = 'PL/SQL' THEN 'PL/SQL is developed by Oracle Corporation.'
	WHEN Tutorial_name = 'MS-SQL' THEN 'MS-SQL is developed by Microsoft Corporation.'
END AS Description
FROM Guru99

结果:下图解释了带有 NO ELSE 的搜索 CASE 的执行流程。

Searched CASE example in SQL Server

查询 2:带有 ELSE 选项的搜索 CASE

SELECT Tutorial_ID, Tutorial_name,
CASE 
	WHEN Tutorial_name = 'SQL' THEN 'SQL is developed by IBM'
	WHEN Tutorial_name = 'PL/SQL' THEN 'PL/SQL is developed by Oracle Corporation.'
	WHEN Tutorial_name = 'MS-SQL' THEN 'MS-SQL is developed by Microsoft Corporation.'
	ELSE 'This is NO SQL language.'
END AS Description
FROM Guru99

结果:下图解释了带有 ELSE 的搜索 CASE 的执行流程。

Searched CASE in SQL Server

执行方法之间的区别:简单 CASE 和搜索 CASE。

让我们看下面的简单 CASE 示例

SELECT Tutorial_ID, Tutorial_name,
CASE Tutorial_name
	WHEN 'SQL' THEN 'SQL is developed by IBM'
	WHEN 'PL/SQL' THEN 'PL/SQL is developed by Oracle Corporation.'
	WHEN 'MS-SQL' THEN 'MS-SQL is developed by Microsoft Corporation.'
	ELSE 'This is NO SQL language.'
END AS Description
FROM Guru99

在这里,‘Tutorial_name’ 是 SQL 中 CASE 表达式的一部分。然后‘Tutorial_name’ 的值与每个WHEN 值进行比较,即‘SQL’……直到‘Tutorial_name’与 WHEN 值匹配。

相反,搜索 CASE 示例没有CASE 表达式

SELECT Tutorial_ID, Tutorial_name,
CASE 
 	WHEN Tutorial_name = 'SQL' THEN 'SQL is developed by IBM'
	WHEN Tutorial_name = 'PL/SQL' THEN 'PL/SQL is developed by Oracle Corporation.'
	WHEN Tutorial_name = 'MS-SQL' THEN 'MS-SQL is developed by Microsoft Corporation.'
END AS Description
FROM Guru99

这里,每个WHEN 语句都有其条件布尔表达式。每个布尔表达式,即 Tutorial_name = ‘SQL’,…,都被评估为真/假,直到第一个布尔表达式评估为

简单 CASE 和搜索 CASE 之间的区别

简单 Case 搜索 Case
CASE 关键字后面直接跟 CASE_Expression,在 WHEN 语句之前。

例如:
CASE <Case_Expression>
WHEN Value_1 THEN Statement_1…

Case 关键字后面跟 WHEN 语句,CASE 和 WHEN 之间没有表达式。

例如:
CASE WHEN <Boolean_Expression_1> THEN Statement_1…

在简单 Case 中,每个 WHEN 语句都有 VALUE。这些值:Value_1、Value_2… 按顺序与单个 CASE_Expression 进行比较。结果将为每个 WHEN 语句评估为真/假条件。

例如:
CASE <Case_Expression>
WHEN Value_1 THEN Statement_1…
WHEN Value_2 THEN Statement_2…

在搜索 Case 中,每个 WHEN 语句都有 Boolean_Expression。这些 Boolean_Expressions:Boolean_Expression_1、Boolean_Expression_2… 为每个 WHEN 语句评估真/假条件。

例如:
CASE
WHEN <Boolean_Expression_1> THEN Statement_1…
WHEN <Boolean_Expression_2> THEN Statement_2…

简单 Case 只支持相等性检查。即 CASE_Expression = VALUE_1, VALUE_2…

例如:
CASE <Case_Expression>WHEN Value_1 THEN Statement_1…在上面的例子中,系统执行的唯一操作是检查 Case_Expression = Value_1

通过 Boolean_Expression_N,搜索 Case 支持任何返回布尔值的操作。它包括等于和不等于运算符。

例如:
CASE WHEN <Boolean_Expression_1> THEN Statement_1…在上面的例子中,Boolean_Expression_1 可以包含“等于”和“不等于”运算符,例如 A = B, A != B。

嵌套 CASE:IF ELSE 中的 CASE

我们可以在 IF ELSE 中使用 CASE。下面是一个 MS-SQL 代码示例

DECLARE @Flight_Ticket int;
SET @Flight_Ticket = 190;
IF @Flight_Ticket > 400
   PRINT 'Visit Nearby Tourist Location';
ELSE 
BEGIN
    SELECT
	CASE 
	WHEN @Flight_Ticket BETWEEN 0 AND 100 THEN 'Visit Los Angeles'
	WHEN @Flight_Ticket BETWEEN 101 AND 200 THEN 'Visit New York'
	WHEN @Flight_Ticket BETWEEN 201 AND 400 THEN 'Visit Europe'
	END AS Location	
END

在上面的示例中,CASE 嵌套在 IF…ELSE 语句中

首先,如果 IF 语句执行,并且 SQL server 中的 Case 条件为假,则 ELSE 语句将执行。

Else 包含 Nested CASE Statement in SQL。根据机票价格,将显示以下结果中的一个

  • 如果机票价格大于400美元,系统将打印“参观附近的旅游地点”
  • 如果机票价格在0美元到100美元之间,系统将打印“访问洛杉矶”
  • 如果机票价格在101美元到200美元之间,系统将打印“访问纽约”
  • 如果机票价格在201美元到400美元之间,系统将打印“访问欧洲”

Nested CASE in SQL Server

嵌套 CASE:CASE 嵌套 CASE

我们可以在 SQL 中使用 CASE 嵌套 CASE。下面是一个 MS-SQL 代码示例

DECLARE @Flight_Ticket int;
SET @Flight_Ticket = 250;
SELECT
CASE 
WHEN @Flight_Ticket >= 400 THEN 'Visit Nearby Tourist Location.'
WHEN @Flight_Ticket < 400 THEN 
    	CASE 
		WHEN @Flight_Ticket BETWEEN 0 AND 100 THEN 'Visit Los Angeles'
		WHEN @Flight_Ticket BETWEEN 101 AND 200 THEN 'Visit New York'
		WHEN @Flight_Ticket BETWEEN 201 AND 400 THEN 'Visit Europe'
		END	
END AS Location

在上面的示例中,CASE 嵌套在另一个 CASE 语句中

系统从执行外部 CASE 开始。如果 Flight_Ticket < 400 美元,则内部 CASE 将执行。

根据机票价格,将显示以下结果中的一个

  • 如果机票价格大于400美元,系统将打印“参观附近的旅游地点”
  • 如果机票价格在0美元到100美元之间,系统将打印“访问洛杉矶”
  • 如果机票价格在101美元到200美元之间,系统将打印“访问纽约”
  • 如果机票价格在201美元到400美元之间,系统将打印“访问欧洲”

Nested CASE example in SQL Server

带 UPDATE 的 CASE

假设:假设我们有一个名为“Guru99”的表,其中包含两列和四行,如下所示

CASE with UPDATE in SQL Server

我们将在后续示例中使用“Guru99”表

我们可以将 CASE 与 UPDATE 一起使用。下面是一个 MS-SQL 代码示例

UPDATE Guru99
SET Tutorial_Name = 
	(
	CASE
	WHEN Tutorial_Name = 'SQL' THEN 'Structured Query language.'
	WHEN Tutorial_Name = 'PL/SQL' THEN 'Oracle PL/SQL'
	WHEN Tutorial_Name = 'MSSQL' THEN 'Microsoft SQL.'
	WHEN Tutorial_Name = 'Hadoop' THEN 'Apache Hadoop.'
	END
	)

在上面的示例中,CASE 用于 UPDATE 语句中。

根据 Tutorial_Name 的值,Tutorial_Name 列将使用 THEN Statement 的值进行更新。

  • 如果 Tutorial_Name = ‘SQL’ 则将 Tutorial_Name 更新为 ‘Structured Query language’
  • 如果 Tutorial_Name = ‘PL/SQL’ 则将 Tutorial_Name 更新为 ‘Oracle PL/SQL’
  • 如果 Tutorial_Name = ‘MSSQL’ 则将 Tutorial_Name 更新为 ‘Microsoft SQL’
  • 如果 Tutorial_Name = ‘Hadoop’ 则将 Tutorial_Name 更新为 ‘Apache Hadoop’

CASE with UPDATE in SQL Server

让我们查询 Guru99 表以检查更新后的值

CASE with UPDATE in SQL Server

带 ORDER BY 的 CASE

我们可以将 CASE 与 ORDER BY 一起使用。下面是一个 MS-SQL 代码示例

Declare @Order Int;
Set @Order = 1
Select * from Guru99 order by 
CASE 
	WHEN @Order = 1 THEN Tutorial_ID
	WHEN @Order = 2 THEN Tutorial_Name
	END
DESC

这里 CASE 与 Order By 一起使用。

@Order 设置为 1,并且由于第一个 WHEN 布尔表达式评估为真,因此选择 Tutorial_ID 作为 Order by 条件

CASE with Order by in SQL Server

有趣的事实!

  • CASE 也可以嵌套在另一个 CASE 中,也可以嵌套在另一个 IF…ELSE 语句中。
  • 除了 SELECT 之外,CASE 还可以与 UPDATE、ORDER BY 等其他 SQL 子句一起使用。

摘要

  • 在 MS SQL 中,CASE 有两种类型:简单 CASE 和搜索 CASE
  • CASE 语句中的 ELSE 是可选的。