T-SQL查询——基于列的逻辑表达式

   T-SQL不仅仅是一个用于查询数据库的语言,还是一个可以对数据进行操作的语言。基于列的case表达式就是其中一种,不像其他查询语言可以互相替代(比如用子查询实现的查询也可以使用join来实现),case表达式在控制基于列的逻辑表达式大部分是无法替代的。

   基于列的逻辑表达式,其实就是case表达式,可以用在select,update,delete,set以及in,where,order by和having子句之后。由于这里讲的是T-SQL查询,所以只说到case表达式在select子句和order by子句中的使用。

  case表达式实现的功能类似编程语言中的if....then....else逻辑,只是case表达式在T-SQL中不能控制T-SQL程序的流程,只是作为基于列的逻辑使用。

  一个简单的case表达式如下:

   我已经知道表中员工ID对应姓名,我想获得员工ID,并将员工ID以姓名的方式展现出来,我不知道的员工ID则显示Unknow  

select top 4 case  employeeID
when 1 then '小王'
when 2 then '小李'
when 3 then '小赵'
else '不知道'
end as 姓名列表,EmployeeID
from advertureWorks.humanResources.Employee
order by EmployeeID

case后面跟选择的列明,后面的when所取得值为EmployeeID这一列,then后面的值为对应前面when后面列中,实际在结果中显示的值。

case表达式实际情况下可以分为两种:

case简单表达式:将某个表达式与一组简单表达式进行比较以确定结果。

case搜索表达式:计算一组布尔表达式以确定结果。

case简单表达式

   在case简单表示中,整个表达式只会取一列的值做相应的判断,上面的查询例子就是一个case简单表达式,可以用图表示:

case表达式可以用这样的写法:

SELECT TOP 4 NameList=CASE EmployeeID
WHEN 1 THEN 'CareySon'
WHEN 2 THEN 'Jack'
WHEN 3 THEN 'Tom'
ELSE 'UNKNOW'
END,EmployeeID
FROM [AdventureWorks].[HumanResources].[Employee]
ORDER BY EmployeeID

上面的代码和前面代码所达到的效果是一模一样的,从这个代码可以看出,case表达式的结果实际上只局限在一列但中,这也是为什么case表达式是基于“基于列的逻辑表达式”

  因为case表达式的值只局限列在一列当中,所以then后面的值数据类型必须相同,或者兼容,否则就会报错。

上面的语句中,还有一个可选的”else“语句,这个语句可以省略,但最好的做法是保留else,否则不在匹配值范围内的所有值都会为”null“。

case搜索表达式

   与case简单表达式不同,case搜索表达式提供了更强大的功能,case搜索表达式不仅可以使用更复杂的逻辑表达式,并且还能根据多列中的数据确定所显示列的值。

SELECT TOP 4 NameList=CASE 
WHEN EmployeeID=1 THEN 'CareySon'
WHEN EmployeeID=1 THEN 'Jack'
WHEN EmployeeID=3 THEN 'Tom'
ELSE 'UNKNOW'
END,EmployeeID
FROM [AdventureWorks].[HumanResources].[Employee]
ORDER BY EmployeeID

case搜索表达式更复杂的引用比如:

公司规定每个人病假或者休息每年都不应该超过30个小时,现在我想取得多有男性员工的ID,其中员工病假或者是休假任意一项超过了30个小时,标记为”Exceed the time“,两项都超过30个小时的,标记为"Not Exceed the time"

select  EmployeeID,
case
when vacationHours>30 and Gender='M' then 'Exceed the Time'
when SickLeaveHours>30 and Gender='M' then 'Exceed the Time'
else 'Not Exceed The Time'
end as Condition
from AdvertureWorks.HumanResources.Employee

查询结果如下:

 上面可以看到,搜索表达式一列的when表达式可以取自不同列,甚至是不同列之间的运算(比如上面可以取when VacationHours+SickLeaveHours>60),这个大大增强了case表达式的功能,因为case搜索表达式可以完全实现case简单表达式所能实现的功能,我个人认为所有的case表达式都应该写成case搜索表达式的形式。

 还有要注意when then是以先后顺序出现,当一个when后面的表达式为false时,则会去看第二个when后的表达式,以此类推。当第一个when后的表达式为true时,则取第一个then后面的值,即使第二个when表达式也为true

  例如:我已经知道员工ID对应的姓名,我想获得员工ID,并将员工ID以姓名的方式展现出来,我不知道的员工ID则显示Unknow

SELECT  NameList=CASE     WHEN EmployeeID=1 THEN 'CareySon'
WHEN EmployeeID=1 THEN 'Jack'
WHEN EmployeeID=3 THEN 'Tom'
ELSE 'UNKNOW'
END,EmployeeID
FROM [AdventureWorks].[HumanResources].[Employee]
ORDER BY EmployeeID

 结果如下:

case表达式在order by中的使用

    case表达式在order by中可以将排序结果分类,并符合某些条件的行(row)采用一种排序方式,符合另一种条件的行采用另一种排序方式。

   比如:我想查看省份ID为8和9的员工地址,当省份ID为9时,按照AddressID降序排列,当省份为8时,按照AddressID升序排列

SELECT [AddressID]
,[AddressLine1]
,[City]
,[StateProvinceID]
FROM [AdventureWorks].[Person].[Address]
WHERE StateProvinceID=9 OR StateProvinceID=8
ORDER BY
CASE WHEN StateProvinceID=9 THEN AddressID END DESC,
CASE WHEN StateProvinceID=8 THEN AddressID END

结果如下:

 注意这里,每一条排序规则都要写一个单独的case表达式,前面文章说了,因为case表达式是基于列的,一个case表达式只能返回一个值,所以基于多少个值排序,则需要多少个case表达式。

总结

    文章讲述了case表达式在select子句中和order by子句中的使用,case表达式又进一步分为case简单表达式和case搜索表达式。掌握使用case表达式可以使程序员将一部分需要在程序中的业务逻辑移动数据库中。

转自http://www.cnblogs.com/CareySon/archive/2011/08/11/2135214.html

posted @ 2012-01-31 12:29  指尖流淌  阅读(611)  评论(0编辑  收藏  举报