SQL语法 CAST、MOD的使用

题目:

(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 表示给结果取别名

想了解更多此题解法,可以去leetcode原题链接:1873. 计算特殊奖金 - 力扣(Leetcode)


(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,这里可能大家会问,干嘛不这样写,不是更简单吗?

# 错误写法
DELETE from Person where id NOT in (
   SELECT min(id) id from Person group by email 
)

刚开始我也跟大家这样想,这样写看起来的确没什么毛病,而且语句也少了一条,但是当你执行的时候,会发现报错:You can't specify target table 'Person' for update in FROM clause

后来通过查阅资料才知道:SQL不允许同时对同一张表即执行查询又执行删除,也就是这两条语句不能同时发生在同一张表中,所以就需要用到一张临时表

 想了解更多此题解法,可以去leetcode原题链接:196. 删除重复的电子邮箱 - 力扣(Leetcode)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值