文章目录
环境
- MySQL 8.0.34 (Linux CentOS)
- MySQL Workbench 8.0 Community (Windows 11 家庭版)
case语法
case
有点类似于其它编程语言的 switch
语句,从多个条件分支中选择一个。
case
有两种写法:
case xxx when xxx then xxx ... else xxx end
case when xxx then xxx ... else xxx end
其中, else
分支是可选的。
select
第一种写法中, when
值是和前面 case
的值作比较。比如:
sql
SELECT
CASE 1 + 1
WHEN 1 THEN 'result = 1'
WHEN 2 THEN 'result = 2'
WHEN 3 THEN 'result = 3'
ELSE 'result = none'
END
运行结果是:
powershell
result = 2
第二种写法中, when
值本身是一个布尔表达式。比如:
sql
SELECT
CASE
WHEN 1 + 2 < 0 THEN 'first'
WHEN 2 + 3 = 5 THEN 'second'
WHEN 3 + 4 >= 7 THEN 'third'
ELSE 'unknown'
END;
运行结果是:
powershell
second
注意:在各分支之间,无需显式 break
,一旦匹配上,就会自动break出来。本例中,虽然第3种情况也正确,但已没有机会了。
where
case
不但可以用在 select
处,也可以用在别处,比如 where
和 order by
。
假设 t1
表中记录了每个员工的部门和工资,现在要查询高工资的员工:
- deptid为1的高工资标准是8000元
- deptid为2的高工资标准是5000元
- 对于其它部门,全部列出来
可以用 union all
来拼接多个查询结果:
sql
select * from t1
where deptid = 1 and salary > 8000
union all
select * from t1
where deptid = 2 and salary > 5000
union all
select * from t1
where deptid <> 1 and deptid <> 2
也可以用 case
来实现:
sql
SELECT * FROM t1
WHERE
CASE deptid
WHEN 1 THEN salary > 8000
WHEN 2 THEN salary > 5000
ELSE TRUE
END;
order by
查询员工信息,要求:
- deptid为1的员工按工资排序
- deptid为2的员工按ID排序
- 对于其它部门,按工资排序
sql
SELECT * FROM t1
ORDER BY CASE deptid
WHEN 1 THEN salary
WHEN 2 THEN id
ELSE salary
END;
注意:如果要添加 asc
/ desc
,只能在 case
之后添加,不能单独在每个 when
分支处添加。
如果其中一个分支想反序,对于数值类型,可以通过 xxx * (-1)
的方式实现,对于其它类型,好像没有简单方法。
考一考
现有 uchome_game
表,每条记录是一盘比赛,其外键有:
-
该盘比赛的两个选手,分别是
uid1
和uid2
-
该盘比赛所在的赛事ID
eventid
现在,对指定的 uid
和 eventid
,查询这个选手在该赛事中的所有对手ID。
答:可以用 union
来实现:
sql
select uid1 as uid from uchome_game where uid2 = 110785 and eventid = 92767
union
select uid2 as uid from uchome_game where uid1 = 110785 and eventid = 92767;
也可以用 case
来实现:
sql
SELECT DISTINCT
CASE
WHEN uid1 = 110785 THEN uid2
ELSE uid1
END AS uid
FROM
uchome_game
WHERE
eventid = 92767 AND (uid1 = 110785 OR uid2 = 110785)
注意:第一个SQL不需要 distinct
,因为 union
会去重。第二个SQL需要用 distinct
去重。