SQL中 case when then else end的用法

基础简介

当我们需要从数据源上直接判断数据显示所代表的含义时 ,可以在SQL语句中使用 Case When 函数。

case有两种格式:简单case函数和case搜索函数。

--简单case函数

 CASE [col_name] WHEN [value1] THEN [result1]…ELSE [default] END
--例如
case sex
     when '1' then '男'
     when '2' then '女'
     else '其他' end

--case搜索函数            

CASE WHEN [expr] THEN [result1]…ELSE [default] END
--例如
case when sex = '1' then '男'
     when sex = '2' then '女'
     else '其他' end

这两种方式,可以实现相同的功能。简单case函数的写法相对比较简洁,但是和case搜索函数相比,功能方面会有些限制,如写判定式。 还有一个需要注重的问题,case函数只返回第一个符合条件的值,剩下的case部分将会被自动忽略。

--例如,下面这段sql,永远无法得到结果“第二类”:           

case when col_1 in ( 'a', 'b') then'第一类'
     when col_1 in ('a')  then '第二类'
     else '其他' end

在Check中使用Case函数

很多情况下,在Check中使用Case函数都是非常不错的解决方法。可能有很多人经常不用Check,那么我建议你看过下面的例子之后也尝试在SQL中使用Check。下面我们看一个实例:公司A有个规定,女职员的工资必须高于1000块,使用Check和Case来体现,如下所示 

CONSTRAINT check_salary CHECK 
           ( CASE WHEN sex = '2' 
                  THEN CASE WHEN salary > 1000 
                        THEN 1 ELSE 0 END 
                  ELSE 1 END = 1 ) 
--如果单纯使用Check
CONSTRAINT check_salary CHECK 
           ( sex = '2' AND salary > 1000 ) 
--这时符合了女职员的条件,但男职员无法输入

两个表数据是否一致的检查

Case函数不同于DECODE函数,在Case函数中,可以使用BETWEEN、LIKE、IS NULL、IN、EXISTS等。如使用IN、EXISTS,可以进行子查询,从而 实现更多的功能。 
实例:有两个表 tbl_A、tbl_B,两个表中都有 keyCol 列,需要对两个表进行比较,tbl_A 中的 keyCol 列数据如果在 tbl_B 中的 keyCol 列数据中可以找到,返回结果'Matched',如果没有找到,返回结果'Unmatched'。 要实现这个功能,可以使用下面两条语句:使用IN 和 EXISTS的结果相同,也可以使用 NOT IN 和 NOT EXISTS,但这时要注意 NULL的情况。

--使用IN时
SELECT keyCol, 
CASE WHEN keyCol IN ( SELECT keyCol FROM tbl_B ) 
    THEN 'Matched' 
    ELSE 'Unmatched' END Label 
FROM tbl_A; 

--使用EXISTS时
SELECT keyCol, 
CASE WHEN EXISTS ( SELECT * FROM tbl_B 
     WHERE tbl_A.keyCol = tbl_B.keyCol ) 
     THEN 'Matched' 
     ELSE 'Unmatched' END Label 
FROM tbl_A; 

 在Case函数中使用合计函数

假设有一张学生表:

学号(std_id)课程ID(class_id)课程名(class_name)主修flag(main_class_flg) 
100 1经济学Y
1002历史学N
2002历史学N
2003考古学Y
2004计算机N
3004计算机N
4005管理学N
5006心理学N

 

 

 

 

 

 

 

 

 

可以看出,有部分学生同时选择修多门课程(100,200),也有部分学生只选择一门课程(300,400,500)。选修多门课程的学生,要选择其中一门课程作为主修,主修flag里面写入 Y;只选择一门课程的学生,主修flag为N (实际上要是写入Y的话,就没有下面的麻烦事了,为了举例子)。 
现在我们要按照下面两个条件对这个表进行查询 :1、只选修一门课程的学生,返回该课程的ID ;2、选修多门课程的学生,返回所选的主课程ID 

最简单的方法是执行两条不同的SQL语句进行查询,代码如下:

--条件1:只选择一门课程的学生 
SELECT std_id, MAX(class_id) AS main_class 
FROM Studentclass 
GROUP BY std_id 
HAVING COUNT(*) = 1; 

--条件2:选择多门课程的学生 
SELECT std_id, class_id AS main_class 
FROM Studentclass 
WHERE main_class_flg = 'Y' ; 

如果使用Case函数,只需要一条SQL语句就可以解决两个查询问题,具体代码如下:

SELECT  std_id, 
CASE WHEN COUNT(*) = 1    --只选择一门课程的学生 
     THEN MAX(class_id) 
     ELSE MAX(CASE WHEN main_class_flg = 'Y' --选择多门课程的学生
              THEN class_id 
              ELSE NULL END 
    ) 
    END AS main_class 
FROM Studentclass 
GROUP BY std_id; 

通过在Case函数中嵌套Case函数,在Case函数中使用合计函数等方法,我们可以轻松的解决这个问题,使用Case函数给我们带来了更大的自由度。 最后提醒一下使用Case函数的新手注意不要犯下面的错误 

CASE col_1 
    WHEN 1   THEN 'Right' 
    WHEN NULL  THEN 'Wrong' 
END 

在这个语句中When Null 这一行总是返回unknown,所以永远不会出现Wrong的情况。因为这句可以替换成WHEN col_1 = NULL,这是一个错误用法,正确的使用方法是WHEN col_1 IS NULL。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值