芯が強い人になるESTJ-A

# SQL之CASE WHEN用法详解

IT開発 Tags: 无标签 阅读: 140

简单CASE WHEN函数:

CASE SCORE WHEN 'A' THEN '优' ELSE '不及格' END
CASE SCORE WHEN 'B' THEN '良' ELSE '不及格' END
CASE SCORE WHEN 'C' THEN '中' ELSE '不及格' END

等同于,使用CASE WHEN条件表达式函数实现:

CASE WHEN SCORE = 'A' THEN '优'
     WHEN SCORE = 'B' THEN '良'
     WHEN SCORE = 'C' THEN '中' ELSE '不及格' END

题目:
(1)写出一个SQL 查询语句,计算每个雇员的奖金。如果一个雇员的id是奇数并且他的名字不是以'M'开头,那么他的奖金是他工资的100%,否则奖金为0。



输入:
Employees 表:
+-------------+---------+--------+
| employee_id | name    | salary |
+-------------+---------+--------+
| 2           | Meir    | 3000   |
| 3           | Michael | 3800   |
| 7           | Addilyn | 7400   |
| 8           | Juan    | 6100   |
| 9           | Kannon  | 7700   |
+-------------+---------+--------+

输出:
+-------------+-------+
| employee_id | bonus |
+-------------+-------+
| 2           | 0     |
| 3           | 0     |
| 7           | 7400  |
| 8           | 0     |
| 9           | 7700  |
+-------------+-------+
解释:
因为雇员id是偶数,所以雇员id 是2和8的两个雇员得到的奖金是0。
雇员id为3的因为他的名字以'M'开头,所以,奖金是0。
其他的雇员得到了百分之百的奖金

解法一: union:合并查询结果

select employee_id,salary AS bonus 
            from Employees where employee_id % 2 != 0 and name not like 'M%'
union    
select employee_id,salary*0 AS bonus 
            from Employees where employee_id % 2 = 0 or name like 'M%'
order by employee_id;

解法二: 使用case语句, when 条件 then 条件满足时返回的结果 以end结尾

select employee_id,
case
    when mod(employee_id,2) <> 0 and left(name,1) <> 'M' then salary
    when mod(employee_id,2) = 0 or left(name,1) = 'M' then 0
end AS bonus
from Employees
order by employee_id

这里再补充一下: mod取余,比如 mod(10,2) 等价于 10%2。 left(name,1):表示取字段name的第一个字母。 <> 等价于 != (不等于号) 后面的 AS bonus 表示给结果取别名

(2)编写一个 SQL 删除语句来 删除 所有重复的电子邮件,只保留一个id最小的唯一电子邮件。以 任意顺序 返回结果表。 (注意: 仅需要写删除语句,将自动对剩余结果进行查询)

示例:
 
输入: 
Person 表:
+----+------------------+
| id | email            |
+----+------------------+
| 1  | john@example.com |
| 2  | bob@example.com  |
| 3  | john@example.com |
+----+------------------+
输出: 
+----+------------------+
| id | email            |
+----+------------------+
| 1  | john@example.com |
| 2  | bob@example.com  |
+----+------------------+
解释: john@example.com重复两次。我们保留最小的Id = 1




解法一:使用表自连接

DELETE p1 from Person p1,Person p2 where p1.email = p2.email and p1.id > p2.id

解析:这里如果细心的小伙伴就会发现,这条语句跟我们平时使用的delete删除语法好像不太一样: delete from 表名 where 条件

可能我也是跟大家一样,第一次接触这种写法,解法一语句具体的意思是说: 当where条件满足时,只删除表p1 的数据,跟表p2无关,这里换一种写法

DELETE p1 from Person p1
left join Person p2
on p1.email = p2.email and p1.id > p2.id

解法二:


DELETE from Person where id NOT in (
   SELECT id from ( SELECT min(id) id from Person group by email ) t
)

解析: SELECT id from ( SELECT min(id) id from Person group by email ) t 表示将(SELECT min(id) id from Person group by email)查询出来的结果作为临时表,取别名 t,这里可能大家会问,干嘛不这样写,不是更简单吗?

t=temp