https://leetcode.cn/study-plan/sql/?progress=jgmzq5s
第1天 选择
595. 大的国家
无
1757. 可回收且低脂的产品
枚举类型enum
enum是一个字符串对象,用于指定一组预定义的值,并可在创建表时使用,如sex取值为 ('male', 'female', 'unknown')
若要使用条件过滤,如过滤出男性,直接 sex = 'male' 就行
584. 寻找用户推荐人
is null的情况
Q:返回客户列表,列表中客户的推荐人的编号都不是2,直接 referee_id != 2
注意只写这个条件的话,推荐人编号为null的也不会输出
所以最后的过滤条件应该是 referee_id != 2 or referee_id is null
是 is null,而不是 = null
183. 从不订购的客户
Q:两个表,Customers表(有Id和Name两列)和Orders表(有Id和CustomerId两列),返回一列客户的姓名即可,列名叫Customers
select Name as Customers
from Customers a left join Orders b
on a.Id = b.CustomerId
where b.CustomerId is null
left join ... on 连接条件 where 过滤条件
不考虑where条件下,left join会把左表所有数据查询出来,on及其后面的条件仅仅会影响右表的数据(符合就显示,不符合全部为null)
在匹配阶段,where子句的条件都不会被使用,仅在匹配阶段完成以后,where子句条件才会被使用,它将从匹配阶段产生的数据中检索过滤
where放后面:先连接生成临时查询结果,然后再筛选
on放后面:先根据条件过滤筛选,再连接生成临时查询结果
第2天 排序&修改
1873. 计算特殊奖金
Q:表Employees有3列employee_id、name、salary,返回两列employee_id、奖金bonus(结果按employee_id排序)。如果一个雇员的id是奇数,且他的名字不是以 'M' 开头,则他的奖金就是他的工资,否则奖金为0
雇员的id是奇数:employee_id % 2 != 0
名字不是以 'M' 开头:left (name, 1) <> 'M'
select employee_id,
case when employee_id%2 != 0 and left(name,1) <> 'M'
then salary
else 0 end as bonus
from Employees
order by employee_id
left(str, length)
str是要提取子字符串的字符串;length是一个正整数,指定将从左边返回的字符数
left() 函数:从左开始截取字符串,length是截取的长度
case when ... then ... else ... end
case具有两种格式 —— 简单case函数和case搜索函数
简单case函数
case sex
when '1' then '男'
when '2' then '女'
else '其他' end
case搜索函数
case when sex = '1' then '男'
when sex = '2' then '女'
else '其他' end
这两种方式可以实现相同的功能。简单case函数的写法相对比较简洁,但是和case搜索函数相比,功能方面会有些限制,比如写判定式
627. 变更性别
Q:Salary表有4列,本题要将sex列的 'm' 和 'f' 互换
要求:仅使用单个update语句,且不产生中间临时表(不能使用select语句)
update Salary
set sex=(
case sex when 'm' then 'f' else 'm' end
)
update ... set ... where...
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
196. 删除重复的电子邮箱
Q:表Person有两列id和email,删除所有重复的电子邮件,只保留一个id最小的唯一电子邮件
delete from Person
where id not in(
select * from(
select min(id) from Person
group by email
) t
)
注意,子查询出来的结果要取别名
第3天 字符串处理函数/正则
1667. 修复表中的名字
Q:表Users有两列user_id和name,使name只有第一个字符是大写,其余都是小写。返回结果按user_id排序
select user_id,
concat(upper(left(name,1)), lower(right(name,length(name)-1))) as name
from Users
order by user_id
concat()、upper()、lower()
concat() 可以将多个字符串拼接在一起
upper() 将字符串中所有字符转为大写
lower() 将字符串中所有字符转为小写
1484. 按日期分组销售产品
Q:表Activities有两列sell_date和product,查找每个日期销售的不同产品的数量及名称(按词典序排列)。返回3列,分别为sell_date、num_sold、products,并按sell_date排序
select sell_date,
count(distinct product) as num_sold,
group_concat(distinct product) as products
from Activities
group by sell_date
order by sell_date
group_concat()
SELECT id, GROUP_CONCAT(score) from score GROUP BY id;
1527. 患某种疾病的患者
Q:表Patients,有三列patient_id、patient_name和conditions。其中conditions包含0个或以上的疾病代码,以空格分隔。返回还是这三列,但是是患有I类糖尿病的患者信息(I类糖尿病的代码总是包含前缀DIAB1)
select patient_id, patient_name, conditions
from Patients
where conditions like 'DIAB1%'
or conditions like '% DIAB1%'
注意,第二种情况,%和DIAB1之间有一个空格