zoukankan      html  css  js  c++  java
  • SQL中的CASE WHEN用法

    其语法如下:

    1)case vlaue when [compare-value]then reslut [when[compare-value]] then result ...] [else result] end


    (2)case when [condition] then result [when[condition]then result...][else result] end


    第一形式当value=compare-value时返回result


    第二形式当第一个为真值的condition出现时,返回该条件的结果,如果没有匹配的结果值,那么else后的结

    果将被返回,如果没有else部分,那么返回null

    简单例子:
    mysql> SELECT CASE 1 WHEN 1 THEN "one" WHEN 2 THEN "two" ELSE "more" END;
    -> "one"
    mysql> SELECT CASE WHEN 1>0 THEN "true" ELSE "false" END;
    -> "true"
    mysql> SELECT CASE BINARY "B" when "a" then 1 when "b" then 2 END;
    -> NULL

    下面是一个稍微复杂的例子:

    标题:普通行列转换(version 2.0) 
    作者:爱新觉罗.毓华 
    时间:2008-03-09 
    地点:广东深圳 
    说明:普通行列转换(version 1.0)仅针对sql server 2000提供静态和动态写法,version 2.0增加sql server 2005的有关写法。 

    问题:假设有张学生成绩表(tb)如下: 
    姓名 课程 分数 
    张三 语文 74 
    张三 数学 83 
    张三 物理 93 
    李四 语文 74 
    李四 数学 84 
    李四 物理 94 
    想变成(得到如下结果): 
    姓名 语文 数学 物理 
    ---- ---- ---- ---- 
    李四 74 84 94 
    张三 74 83 93 
    ------------------- 
    */ 

    create table tb(姓名 varchar(10) , 课程 varchar(10) , 分数 int) 
    insert into tb values('张三' , '语文' , 74) 
    insert into tb values('张三' , '数学' , 83) 
    insert into tb values('张三' , '物理' , 93) 
    insert into tb values('李四' , '语文' , 74) 
    insert into tb values('李四' , '数学' , 84) 
    insert into tb values('李四' , '物理' , 94) 
    go 

    --SQL SERVER 2000 静态SQL,指课程只有语文、数学、物理这三门课程。(以下同) 
    select 姓名 as 姓名 , 
    max(case 课程 when '语文' then 分数 else 0 end) 语文, 
    max(case 课程 when '数学' then 分数 else 0 end) 数学, 
    max(case 课程 when '物理' then 分数 else 0 end) 物理 
    from tb 
    group by 姓名 

    问题:在上述结果的基础上加平均分,总分,得到如下结果: 
    姓名 语文 数学 物理 平均分 总分 
    ---- ---- ---- ---- ------ ---- 
    李四 74 84 94 84.00 252 
    张三 74 83 93 83.33 250 
    */ 

    --SQL SERVER 2000 静态SQL。 
    select 姓名 姓名, 
    max(case 课程 when '语文' then 分数 else 0 end) 语文, 
    max(case 课程 when '数学' then 分数 else 0 end) 数学, 
    max(case 课程 when '物理' then 分数 else 0 end) 物理, 
    cast(avg(分数*1.0) as decimal(18,2)) 平均分, 
    sum(分数) 总分 
    from tb 
    group by 姓名 

    --SQL SERVER 2005 静态SQL。 
    select m.* , n.平均分 , n.总分 from 
    (select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b) m, 
    (select 姓名 , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名) n 
    where m.姓名 = n.姓名 


    /* 
    问题:如果上述两表互相换一下:即表结构和数据为: 
    姓名 语文 数学 物理 
    张三 74  83  93 
    李四 74  84  94 
    想变成(得到如下结果): 
    姓名 课程 分数 
    ---- ---- ---- 
    李四 语文 74 
    李四 数学 84 
    李四 物理 94 
    张三 语文 74 
    张三 数学 83 
    张三 物理 93 
    -------------- 
    */ 

    create table tb(姓名 varchar(10) , 语文 int , 数学 int , 物理 int) 
    insert into tb values('张三',74,83,93) 
    insert into tb values('李四',74,84,94) 
    go 

    --SQL SERVER 2000 静态SQL。 
    select * from 

    select 姓名 , 课程 = '语文' , 分数 = 语文 from tb 
    union all 
    select 姓名 , 课程 = '数学' , 分数 = 数学 from tb 
    union all 
    select 姓名 , 课程 = '物理' , 分数 = 物理 from tb 
    ) t 
    order by 姓名 , case 课程 when '语文' then 1 when '数学' then 2 when '物理' then 3 end 

    /* 
    问题:在上述的结果上加个平均分,总分,得到如下结果: 
    姓名 课程 分数 
    ---- ------ ------ 
    李四 语文 74.00 
    李四 数学 84.00 
    李四 物理 94.00 
    李四 平均分 84.00 
    李四 总分 252.00 
    张三 语文 74.00 
    张三 数学 83.00 
    张三 物理 93.00 
    张三 平均分 83.33 
    张三 总分 250.00 
    ------------------ 
    */ 

    select * from 

    select 姓名 as 姓名 , 课程 = '语文' , 分数 = 语文 from tb 
    union all 
    select 姓名 as 姓名 , 课程 = '数学' , 分数 = 数学 from tb 
    union all 
    select 姓名 as 姓名 , 课程 = '物理' , 分数 = 物理 from tb 
    union all 
    select 姓名 as 姓名 , 课程 = '平均分' , 分数 = cast((语文 + 数学 + 物理)*1.0/3 as decimal(18,2)) from tb 
    union all 
    select 姓名 as 姓名 , 课程 = '总分' , 分数 = 语文 + 数学 + 物理 from tb 
    ) t 
    order by 姓名 , case 课程 when '语文' then 1 when '数学' then 2 when '物理' then 3 when '平均分' then 4

    case when then end的用法的补充

    当case when then中用到一些的其他的条件的时候,要注意:Select count(case when l.action like 'view%' then action else null end) as pv,count(case when l.action like 'view%' and user_id!='' then user_id else null end) as pv1,count(case when l.action like 'view%' and cookie_id!='' then cookie_id else null end) as pv2from a l,b rswhere l.refer_source1=rs.refer_source1 and l.refer_source2=rs.refer_source2 group by date(log_date),rs.refer_source1,rs.refer_source2

    case when then 中的else后面要返回null,如果放回0,得到的数据就会不正确。

  • 相关阅读:
    外校培训前三节课知识集合纲要(我才不会告诉你我前两节只是单纯的忘了)
    floyd算法----牛栏
    bfs开始--马的遍历
    (DP 线性DP 递推) leetcode 64. Minimum Path Sum
    (DP 线性DP 递推) leetcode 63. Unique Paths II
    (DP 线性DP 递推) leetcode 62. Unique Paths
    (DP 背包) leetcode 198. House Robber
    (贪心 复习) leetcode 1007. Minimum Domino Rotations For Equal Row
    (贪心) leetcode 452. Minimum Number of Arrows to Burst Balloons
    (字符串 栈) leetcode 921. Minimum Add to Make Parentheses Valid
  • 原文地址:https://www.cnblogs.com/duanxz/p/3634777.html
Copyright © 2011-2022 走看看