基础知识
当我们需要从数据源上 直接判断数据显示代表的含义的时候 ,就可以在SQL语句中使用 Case When这个函数了.
Case具有两种格式。简单Case函数和Case搜索函数。
简单函数
CASE [col_name] WHEN [value1] THEN [result1]…ELSE [default] END
搜索函数
CASE WHEN [expr] THEN [result1]…ELSE [default] END
用法介绍
简单Case函数
格式说明
case 列名
when 条件值1 then 选择项1
when 条件值2 then 选项2.......
else 默认值
end
案例1:
SELECT
CASE job_level
WHEN '1' THEN '1111'
WHEN '2' THEN '1111'
WHEN '3' THEN '1111'
ELSE 'eee'
END
FROM
employee
Case搜索函数
格式说明
case
when 列名= 条件值1 then 选择项1
when 列名=条件值2 then 选项2.......
else 默认值
end
案例2:
UPDATE employee
SET e_wage =
CASE
WHEN job_level = '1' THEN e_wage * 1.97
WHEN job_level = '2' THEN e_wage * 1.07
WHEN job_level = '3' THEN e_wage * 1.06
ELSE e_wage * 1.05
END
使用场景
场景1
场景1:有分数score,score<60返回不及格,score>=60返回及格,score>=80返回优秀
SELECT
STUDENT_NAME,
(CASE WHEN score < 60 THEN '不及格'
WHEN score >= 60 AND score < 80 THEN '及格'
WHEN score >= 80 THEN '优秀'
ELSE '异常' END) AS REMARK
FROM
TABLE
注意:如果你想判断score是否null的情况,WHEN score = null THEN '缺席考试',这是一种错误的写法,正确的写法应为:
CASE WHEN score IS NULL THEN '缺席考试' ELSE '正常' END
案例2:
现老师要统计班中,有多少男同学,多少女同学,并统计男同学中有几人及格,女同学中有几人及格,要求用一个SQL输出结果。
表结构如下:其中STU_SEX字段,0表示男生,1表示女生。
STU_CODE | STU_NAME | STU_SEX | STU_SCORE |
---|---|---|---|
XM | 小明 | 0 | 88 |
XL | 小磊 | 0 | 55 |
XF | 小峰 | 0 | 45 |
XH | 小红 | 1 | 66 |
XN | 晓妮 | 1 | 77 |
XY | 小伊 | 1 | 99 |
SELECT
SUM (CASE WHEN STU_SEX = 0 THEN 1 ELSE 0 END) AS MALE_COUNT,
SUM (CASE WHEN STU_SEX = 1 THEN 1 ELSE 0 END) AS FEMALE_COUNT,
SUM (CASE WHEN STU_SCORE >= 60 AND STU_SEX = 0 THEN 1 ELSE 0 END) AS MALE_PASS,
SUM (CASE WHEN STU_SCORE >= 60 AND STU_SEX = 1 THEN 1 ELSE 0 END) AS FEMALE_PASS
FROM
THTF_STUDENTS
输出结果如下:
MALE_COUNT | FEMALE_COUNT | MALE_PASS | FEMALE_PASS |
---|---|---|---|
3 | 3 | 1 | 3 |
场景3:
经典行转列,并配合聚合函数做统计:现要求统计各个城市,总共使用了多少水耗、电耗、热耗,使用一条SQL语句输出结果
有能耗表如下:其中,E_TYPE表示能耗类型,0表示水耗,1表示电耗,2表示热耗
E_CODE | E_VALUE | E_TYPE |
---|---|---|
北京 | 28.50 | 0 |
北京 | 23.51 | 1 |
北京 | 28.12 | 2 |
北京 | 12.30 | 0 |
北京 | 15.46 | 1 |
上海 | 18.88 | 0 |
上海 | 16.66 | 1 |
上海 | 19.99 | 0 |
上海 | 10.05 | 0 |
SELECT
E_CODE,
SUM(CASE WHEN E_TYPE = 0 THEN E_VALUE ELSE 0 END) AS WATER_ENERGY,--水耗
SUM(CASE WHEN E_TYPE = 1 THEN E_VALUE ELSE 0 END) AS ELE_ENERGY,--电耗
SUM(CASE WHEN E_TYPE = 2 THEN E_VALUE ELSE 0 END) AS HEAT_ENERGY--热耗
FROM
THTF_ENERGY_TEST
GROUP BY
E_CODE
输出结果如下:
E_CODE | WATER_ENERGY | ELE_ENERGY | HEAT_ENERGY |
---|---|---|---|
北京 | 40.80 | 38.97 | 28.12 |
上海 | 48.92 | 16.66 | 0 |
场景4:
CASE WHEN中使用子查询:根据城市用电量多少,计算用电成本。假设电能耗单价分为三档,根据不同的能耗值,使用相应价格计算成本。当能耗值小于10时,使用P_LEVEL=0时的P_PRICE的值,能耗值大于10小于30使用P_LEVEL=1时的P_PRICE的值...
价格表如下:
P_PRICE | P_LEVEL | P_LIMIT |
---|---|---|
1.20 | 0 | 10 |
1.70 | 1 | 30 |
2.50 | 2 | 50 |
CASE WHEN energy <= (SELECT P_LIMIT FROM TABLE_PRICE WHERE P_LEVEL = 0) THEN (SELECT P_PRICE FROM TABLE_PRICE WHERE P_LEVEL = 0)
WHEN energy > (SELECT P_LIMIT FROM TABLE_PRICE WHERE P_LEVEL = 0) AND energy <= (SELECT P_LIMIT FROM TABLE_PRICE WHERE P_LEVEL = 1) THEN (SELECT P_PRICE FROM TABLE_PRICE WHERE P_LEVEL = 1)
WHEN energy > (SELECT P_LIMIT FROM TABLE_PRICE WHERE P_LEVEL = 1) AND energy <= (SELECT P_LIMIT FROM TABLE_PRICE WHERE P_LEVEL = 2) THEN (SELECT P_PRICE FROM TABLE_PRICE WHERE P_LEVEL = 2)
练习题
练习题1
已经有一张表名为scores
的学生成绩表,表内的数据如下:
id | class_id | student_id | score |
---|---|---|---|
1 | 1 | 1 | 100 |
2 | 1 | 1 | 90 |
3 | 1 | 1 | 80 |
4 | 1 | 2 | 70 |
5 | 1 | 2 | 60 |
6 | 2 | 3 | 50 |
平均得分与等级之间的转换关系如下表:
得分 | 等级 |
---|---|
>=90 | A |
80-90 | B |
70-80 | C |
60-70 | D |
<60 | E |
请写出班级号为1的学生的学号及各科平均成绩其对应的等级,查询结果按照学生编号顺序排列。
查询结果示例:
student_id | LEVEL |
---|---|
1 | A |
2 | D |
SELECT
temp.student_id,
(
CASE
WHEN ( temp.avg_score >= 90 ) THEN 'A'
WHEN ( temp.avg_score >= 80 AND temp.avg_score < 90 ) THEN 'B'
WHEN ( temp.avg_score >= 70 AND temp.avg_score < 80 ) THEN 'C'
WHEN ( temp.avg_score >= 60 AND temp.avg_score < 70 ) THEN 'D'
WHEN ( temp.avg_score < 60 ) THEN 'E'
END
) AS LEVEL
FROM
( SELECT student_id, AVG( score ) AS avg_score FROM scores WHERE class_id = 1 GROUP BY student_id ) AS temp
ORDER BY
temp.student_id ASC;
联系题2:
首先,向数据库中插入如下的测试数据,code字段表示税号、name字段表示企业名称,value字段表示税后额,month字段表示月份。现在要求合并所有企业5月和6月的税收结果在同一张表中,请写出SQL查询语句。
/*
Navicat MySQL Data Transfer
Date: 2019-07-04 20:11:31
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for tax
-- ----------------------------
DROP TABLE IF EXISTS `tax`;
CREATE TABLE `tax` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`code` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`value` double(20,2) NOT NULL,
`month` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1612 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tax
-- ----------------------------
INSERT INTO `tax` VALUES ('1', '913301225802604739', '浙江万拓房地产有限公司', '8217325.31', '5');
INSERT INTO `tax` VALUES ('2', '913301000980647063', '杭州市桐庐县龙生小额贷款股份有限公司', '4687443.89', '5');
INSERT INTO `tax` VALUES ('3', '91330122557922045C', '浙江通泰房地产有限公司', '3298898.23', '5');
INSERT INTO `tax` VALUES ('4', '9133012267397706XA', '杭州杭千高速石油发展有限公司', '2749974.69', '5');
INSERT INTO `tax` VALUES ('182', '91330122754412626Y', '桐庐明晟五金塑料制品厂', '59973.47', '5');
INSERT INTO `tax` VALUES ('183', '91330122092047374A', '桐庐申翔贸易有限公司', '59791.88', '5');
INSERT INTO `tax` VALUES ('184', '91330122560585828H', '桐庐玉翰置业有限公司', '59447.14', '5');
INSERT INTO `tax` VALUES ('185', '91330122328150053L', '杭州沃科特生物科技有限公司', '59432.87', '5');
INSERT INTO `tax` VALUES ('186', '913301227766368233', '桐庐璟泰帽厂', '59378.73', '5');
INSERT INTO `tax` VALUES ('187', '913301227572167865', '桐庐中新箱包有限公司', '59088.56', '5');
INSERT INTO `tax` VALUES ('188', '91330122MA28XGUR3R', '浙江盛添医疗器械有限公司', '58478.49', '5');
INSERT INTO `tax` VALUES ('189', '91330122MA28WGAT7Y', '杭州商旅经营发展有限公司桐庐北区分公司', '58393.21', '5');
INSERT INTO `tax` VALUES ('190', '91330122694560706A', '杭州拓乐实业有限公司', '58175.11', '5');
INSERT INTO `tax` VALUES ('191', '91330108082110405A', '杭州丰展贸易有限公司', '58170.71', '5');
INSERT INTO `tax` VALUES ('192', '91330122MA2B1RUM0C', '杭州康怡科技贸易有限公司', '58075.73', '5');
INSERT INTO `tax` VALUES ('319', '92330122MA28WW5Q4T', '桐庐县江南镇芬花景观石经营部', '22455.33', '5');
INSERT INTO `tax` VALUES ('320', '92330122MA280M4U9C', '桐庐县江南镇增娟箱包厂', '22447.62', '5');
INSERT INTO `tax` VALUES ('321', '91330122568778667U', '杭州泓威焊锡材料有限公司', '22303.81', '5');
INSERT INTO `tax` VALUES ('322', '91330122MA28NULH8J', '杭州三石医疗器械有限公司', '22194.10', '5');
INSERT INTO `tax` VALUES ('323', '91330122MA2B2G9L48', '杭州恒辉医疗设备有限公司', '22186.01', '5');
INSERT INTO `tax` VALUES ('324', '913301220567142056', '杭州万星物业管理有限公司桐庐分公司', '22058.55', '5');
INSERT INTO `tax` VALUES ('336', '91330122673967021P', '桐庐中远塑业有限公司', '19202.37', '5');
INSERT INTO `tax` VALUES ('337', '91330122609247142P', '杭州永澳经贸有限公司', '19149.02', '5');
INSERT INTO `tax` VALUES ('338', '91330122MA2B29WT71', '桐庐伟恩医疗器械有限公司', '18991.58', '5');
INSERT INTO `tax` VALUES ('339', '91330122MA2CG7UL00', '杭州润霖医疗器械有限公司', '18643.14', '5');
INSERT INTO `tax` VALUES ('340', '92330122MA2BJYUR91', '桐庐县江南镇乐洲橡塑制品商行', '18454.37', '5');
INSERT INTO `tax` VALUES ('341', '9133012206786740X3', '桐庐巨索起重设备有限公司', '18388.92', '5');
INSERT INTO `tax` VALUES ('342', '92330122MA2CFCR32J', '杭州佳罗医疗器械有限公司', '18343.51', '5');
INSERT INTO `tax` VALUES ('1416', '91330104MA28RB2N6W', '杭州均胜信息科技有限公司', '1361.48', '6');
INSERT INTO `tax` VALUES ('1417', '91330122MA2CF0HM11', '杭州正道工匠文化艺术有限公司', '1250.00', '6');
INSERT INTO `tax` VALUES ('1418', '91330122577317395K', '杭州邦辉摩擦材料有限公司', '1249.95', '6');
INSERT INTO `tax` VALUES ('1419', '91330104MA2B1BYA47', '杭州依尼欧贸易有限公司', '1200.31', '6');
INSERT INTO `tax` VALUES ('1420', '92330122MA2CC2256Y', '桐庐县江南镇剑峰五金加工厂',
INSERT INTO `tax` VALUES ('1610', '91330122MA28WYUM6C', '杭州合鑫医疗器械有限公司', '-26209.98', '6');
INSERT INTO `tax` VALUES ('1611', '913301227265865731', '杭州环宇针织有限公司', '-340376.70', '6');
下图为表中部分数据:
select code,name,
sum(case when month=5 then value else 0 end) as month_value_5,
sum(case when month=6 then value else 0 end) as month_value_6
from
tax
GROUP BY
code;
下图给出了部分查询结果: