首页 > 其他 > 详细

小说一下case ~

时间:2016-02-04 12:24:26      阅读:140      评论:0      收藏:0      [点我收藏+]

case 这个关键词,用的地方不少~大部分的用途都通过以下的方式去应用

DECLARE @i INT = 3

SELECT  CASE @i
          WHEN 1 THEN 1
          WHEN 2 THEN 2
          WHEN 3 THEN 3
        END AS 测试1;

测试1
-----------
3


DECLARE @Hour INT = DATEPART(hh,GETDATE())

SELECT CASE WHEN @Hour BETWEEN 7 AND 12 THEN 早上好
            WHEN @Hour >= 12 AND @Hour < 18 THEN 下午好
            WHEN @Hour > 18 AND @Hour < 24 THEN 晚上好
            ELSE 深夜了 END AS 问候


问候
------
早上好
            

这个已经用得炉火纯青╮(╯_╰)╭的小伙伴请不要鄙视我。

补充说一下,第一个查询和第二个查询的区别是第二个查询有一个else ,这个else 是用来处理当都匹配不上的值。如果没有else 的处理,如第一个例子的@i = 4 的时候,表达式将返回 Null。

 

再给一个例子,简单创建一个员工表,然后通过使用case 可以做一些自定义的规则,这里是按部门,优先是秘书处,然后开发部,然后人事部,最后其它部门不分先后,再根据入职时间来一个排序。

CREATE TABLE #Employee (ID INT IDENTITY(1,1),DeparmentName NVARCHAR(50),Name NVARCHAR(50),EntryDate DATETIME)

INSERT INTO #Employee
        ( DeparmentName, Name, EntryDate )
VALUES  ( N人事部,NJoey, 2015-04-12),
        ( N开发部,NJohn, 2013-04-23),
        ( N秘书处,NMery, 2012-03-17),
        ( N人事部,NAnna, 2014-05-07),
        ( N秘书处,NDave, 2011-01-12),
        ( N开发部,NAlex, 2012-03-03)

SELECT *
    FROM #Employee
    ORDER BY CASE DeparmentName WHEN 秘书处 THEN 1
                                WHEN 开发部 THEN 2
                                WHEN 人事部 THEN 3
                                ELSE 4 END,EntryDate
     

ID          DeparmentName                                      Name                                               EntryDate
----------- -------------------------------------------------- -------------------------------------------------- -----------------------
5           秘书处                                                Dave                                               2011-01-12 00:00:00.000
3           秘书处                                                Mery                                               2012-03-17 00:00:00.000
6           开发部                                                Alex                                               2012-03-03 00:00:00.000
2           开发部                                                John                                               2013-04-23 00:00:00.000
4           人事部                                                Anna                                               2014-05-07 00:00:00.000
1           人事部                                                Joey                                               2015-04-12 00:00:00.000

 

使用case 还是要注意一些语法上面的使用,首先是联机文档里面提到的2个

1 case 的嵌套上限是10 

2  以下这个栗子是会执行报0除的错误的。因为 1/value 存在0,所以要注意执行的时候是需要注意表达式的值,不应依赖聚合后的值和when 的顺序,这将会出现意外的结果。

WITH Data (value) AS 
( 
SELECT 0 
UNION ALL 
SELECT 1 
) 
SELECT 
   CASE 
      WHEN MIN(value) <= 0 THEN 0 
      WHEN MAX(1/value) >= 100 THEN 1 
   END 
FROM Data ;

3 注意then 后面的表达式,比如我将前面的查询语句修改一下。因为then 后面的数据类型隐式转换失败,就会报下面的错误,所以这个要小心

SELECT *
    FROM #Employee
    ORDER BY CASE DeparmentName WHEN 秘书处 THEN 1    
                                WHEN 开发部 THEN a  --修改为‘a‘
                                WHEN 人事部 THEN 3
                                ELSE 4 END,EntryDate


消息 245,级别 16,状态 1,第 12 行
在将 varchara 转换成数据类型 int 时失败。

4 不光是 then 后面的 ,when 后面的值也需要注意数据类型的一致性。上述的例子如果将 开发部改成 1(不是 ‘1‘),错误也成立 。

5 还有一种特殊的情况,在case 里面使用函数,每次都会重新调用一次。比如以下一个例子

DECLARE @i INT = 1,
        @j INT

DECLARE @T AS TABLE (I INT)
WHILE @i < 100
BEGIN
    SELECT @j = CASE WHEN CAST(RAND()*10 AS INT)%3 = 0 THEN 0
                  WHEN CAST(RAND()*10 AS INT)%3 = 1 THEN 1
                  WHEN CAST(RAND()*10 AS INT)%3 = 2 THEN 2 END,
           @i = @i + 1
    INSERT INTO @T
            ( I )
    VALUES  ( @j )
END 
SELECT I,COUNT(*)
    FROM @T
    GROUP BY I

I           
----------- -----------
NULL        27
0           34
1           24
2           14

 

( Null???Null怎么会出来的?? rand()*10 % 3 只有 (0,1,2) 3种情况啊!!你挺萌的在逗我?)

其实是这个样纸的,看一下语句,case 里面,没匹配一项,都需要将case when 里面的条件判断一次,所以每次都会执行一次 Rand()*10 这个表达式,导致可以非 1,2,3 的值粗线!如果要稳定,那就改成这样

DECLARE @i INT = 1,
        @j INT

DECLARE @T AS TABLE (I INT)
WHILE @i < 100
BEGIN
    SELECT @j = CAST(RAND()*10 AS INT) ,
           @j = CASE @j%3 WHEN 0 THEN 0
                  WHEN  1 THEN 1
                  WHEN  2 THEN 2 END,
           @i = @i + 1
    INSERT INTO @T
            ( I )
    VALUES  ( @j )
END 
SELECT I,COUNT(*)
    FROM @T
    GROUP BY I


I           
----------- -----------
0           40
1           24
2           35

看!这就没有了Null 了~

 

然后~这就说完了╮(╯_╰)╭

 

小说一下case ~

原文:http://www.cnblogs.com/Gin-23333/p/5181302.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!