标签:ati 没有 不同 arc 重要 上海 统一 表达式 性能
CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE '其他' END
CASE WHEN SEX='1' THEN '男'
WHEN SEX='2' THEN '女'
ELSE '其他' END
简单 CASE 表达式正如其名,写法简单,但能实现的事情比较有限。简单 CASE 表达式能写的条件,搜索CASE表达式也能写,推荐使用搜索case表达式。
我们在编写SQL语句的时候需要注意,在发现为真的 WHEN子句时,CASE表达式的真假值判断就会中止,而剩余的WHEN子句会被忽略。为了避免引起不必要的混乱,使用WHEN子句时要注意条件的排他性。
案例:统计人数
pref_name | population |
---|---|
龙岩 | 500 |
深圳 | 2000 |
...
SELECT CASE pref_name
WHEN '龙岩'THEN '福建'
WHEN '厦门'THEN '福建'
WHEN '福州'THEN '福建'
WHEN '广州'THEN '广东'
WHEN '深圳'THEN '广东'
WHEN '汕头'THEN '广东'
WHEN '杭州'THEN '浙江'
WHEN '温州'THEN '浙江'
WHEN '丁波'THEN '浙江'
ELSE '其他' END AS district,
SUM(population)
from PopTbl
GROUP BY CASE pref_name
WHEN '龙岩'THEN '福建'
WHEN '厦门'THEN '福建'
WHEN '福州'THEN '福建'
WHEN '广州'THEN '广东'
WHEN '深圳'THEN '广东'
WHEN '汕头'THEN '广东'
WHEN '杭州'THEN '浙江'
WHEN '温州'THEN '浙江'
WHEN '丁波'THEN '浙江'
ELSE '其他' END;
按人口等级划分:
SELECT CASE WHEN population < 100 THEN '01'
WHEN population >= 100 AND population < 200 THEN '02'
WHEN population >= 200 AND population < 300 THEN '03'
WHEN population >= 300 THEN '04'
ELSE NULL END AS pop_class,
COUNT(*) AS cnt
FROM PopTbl
GROUP BY CASE WHEN population < 100 THEN '01'
WHEN population >= 100 AND population < 200 THEN '02'
WHEN population >= 200 AND population < 300 THEN '03'
WHEN population >= 300 THEN '04'
ELSE NULL END;
在group by时使用select中定义的别名(当oracle会报错):
SELECT CASE pref_name
WHEN '龙岩'THEN '福建'
WHEN '厦门'THEN '福建'
WHEN '福州'THEN '福建'
WHEN '广州'THEN '广东'
WHEN '深圳'THEN '广东'
WHEN '汕头'THEN '广东'
WHEN '杭州'THEN '浙江'
WHEN '温州'THEN '浙江'
WHEN '丁波'THEN '浙江'
ELSE '其他' END AS district,
SUM(population)
from PopTbl
GROUP BY district;
用一条sql进行不同条件统计:
pref_name | sex | population |
---|---|---|
北京 | 1 | 500 |
北京 | 2 | 550 |
上海 | 1 | 600 |
上海 | 2 | 450 |
统计结果:
pref_name | 男 | 女 |
---|---|---|
北京 | 500 | 550 |
上海 | 600 | 450 |
sql语句:
SELECT pref_name,
SUM(case when sex='1' then population else 0 end) AS '男',
SUM(case when sex='2' then population else 0 end) AS '女'
from poptbl2
GROUP BY pref_name
这里是将“行结构”的数据转换成了“列结构”的数据。除了SUM,COUNT、AVG等聚合函数也都可以用于将行结构的数据转换成列结构的数据,其实就是在SELECT子句进行条件分支。
1.对工资为10000的降薪10%
2.对工资低于8000高于5000的涨薪20%
如果分两次执行,可能造成一些数据重复执行,所以要一次执行
update Salaries
set salary = case when salary >=1000 then salary * 0.9
case when salary>=5000 and salary<=8000 then salary*1.2
else salary end;
SQL 语句最后一行的 ELSE salary 非常重要,必须写上。因为如果没有它,条件 1 和条件2都不满足的员工的工资就会被更新成 NULL 。
这个技巧的应用范围很广。例如,可以用它简单地完成主键值调换这种繁重的工作:
UPDATE SomeTable
SET p_key = CASE WHEN p_key = 'a' THEN 'b'
WHEN p_key = 'b' THEN 'a'
ELSE p_key END
WHERE p_key IN ('a', 'b')
联表匹配数据:
-- 课程一览
CREATE TABLE CourseMaster
(course_id INTEGER PRIMARY KEY,
course_name VARCHAR(32) NOT NULL);
INSERT INTO CourseMaster VALUES(1, '会计入门');
INSERT INTO CourseMaster VALUES(2, '财务知识');
INSERT INTO CourseMaster VALUES(3, '簿记考试');
INSERT INTO CourseMaster VALUES(4, '税务师');
-- 开设的课程
CREATE TABLE OpenCourses
(month INTEGER ,
course_id INTEGER ,
PRIMARY KEY(month, course_id));
INSERT INTO OpenCourses VALUES(200706, 1);
INSERT INTO OpenCourses VALUES(200706, 3);
INSERT INTO OpenCourses VALUES(200706, 4);
INSERT INTO OpenCourses VALUES(200707, 4);
INSERT INTO OpenCourses VALUES(200708, 2);
INSERT INTO OpenCourses VALUES(200708, 4);
生产交叉表:
select course_name,
case when course_id in (select course_id from opencourses where month=200706)
THEN "O" else 'x' end AS "6月",
case when course_id in (select course_id from opencourses where month=200707)
THEN "O" else 'x' end AS "7月",
case when course_id in (select course_id from opencourses where month=200708)
THEN "O" else 'x' end AS "8月"
from CourseMaster;
也可以使用EXISTS,无论使用IN还是EXISTS ,得到的结果是一样的,但从性能方面来说, EXISTS更好。通过EXISTS进行的子查询能够用到“month,course_id”这样的主键索引,因此尤其是当表OpenCourses里数据比较多的时候更有优势
标签:ati 没有 不同 arc 重要 上海 统一 表达式 性能
原文地址:https://www.cnblogs.com/sanzashu/p/10986238.html