627.变更性别

627.变更性别

题目

Salary 表:

1
2
3
4
5
6
7
8
9
10
11
+-------------+----------+
| Column Name | Type |
+-------------+----------+
| id | int |
| name | varchar |
| sex | ENUM |
| salary | int |
+-------------+----------+
id 是这个表的主键(具有唯一值的列)。
sex 这一列的值是 ENUM 类型,只能从 (**m**, **f**) 中取。
本表包含公司雇员的信息。

请你编写一个解决方案来交换所有的 ‘f’‘m’ (即,将所有 ‘f’ 变为 ‘m’ ,反之亦然),仅使用 单个 update 语句 ,且不产生中间临时表。

注意,你必须仅使用一条 update 语句,且 不能 使用 select 语句。

结果如下例所示。

示例 1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
输入:
Salary 表:
+----+------+-----+--------+
| id | name | sex | salary |
+----+------+-----+--------+
| 1 | A | m | 2500 |
| 2 | B | f | 1500 |
| 3 | C | m | 5500 |
| 4 | D | f | 500 |
+----+------+-----+--------+
输出:
+----+------+-----+--------+
| id | name | sex | salary |
+----+------+-----+--------+
| 1 | A | f | 2500 |
| 2 | B | m | 1500 |
| 3 | C | f | 5500 |
| 4 | D | m | 500 |
+----+------+-----+--------+
解释:
(1, A) 和 (3, C) 从 **m** 变为 **f** 。
(2, B) 和 (4, D) 从 **f** 变为 **m** 。

解题思路

要将 sex 列中的 ‘f’ 替换为 ‘m’,同时将 ‘m’ 替换为 ‘f’,直接分两步更新会导致所有值最终变成同一种(例如,先将所有 ‘f’ 转为 ‘m’,那么原先的 ‘m’ 和新转成的 ‘m’ 在下一步都会被转为 ‘f’)。为了避免这个问题,我们需要在一个 UPDATE 语句中,针对每一行数据,根据其 sex 列的当前值来决定其新值。SQL 中的 CASE 语句恰好能实现这种条件判断:当 sex 是 ‘f’ 时,就将其更新为 ‘m’;当 sex 是 ‘m’ 时,就将其更新为 ‘f’。这样,通过一次扫描和判断,就能正确地完成所有值的交换,且无需使用临时表。


详细代码

2

1
2
3
4
5
update Salary
set sex=case
when sex='f' then 'm'
when sex='m' then 'f'
end;