力扣SQL刷题4

1158. 市场分析 I

题型:表1和表2连接时,如何把没有对应数据输出来。即表1中所有id列对应的表2数据输出,没用的输出0
解答1:left join 后用on筛选而不用where筛选
解答2:left join 后,select中用ifnull(x1, x2)
where和on的区别,on是在连接构造临时表时执行的,不管on中条件是否成立都会返回主表(也就是left join左边的表)的内容,where是在临时表形成后执行筛选作用的,不满足条件的整行都会被过滤掉。如果这里用的是 where year(order_date)=‘2019’ 那么得到的结果将会把不满足条件的user_id为3,4的行给删掉。用on的话会保留user_id为3,4的行。

ifnull(x1, x2) 函数:
ifnull(x1, x2) :如果 x1 为 NULL就返回 x2,否则返回 x1。
在这里插入图片描述
在这里插入图片描述
法一:把筛选条件加在on里面

select u.user_id as buyer_id,u.join_date,count(order_id) orders_in_2019
from Orders o right join Users u on o.buyer_id = u.user_id and year(o.order_date) = 2019
group by u.user_id

法二:次数在一个表里先算出来,再右连接另一个表,次数为空的用一下ifnull函数

select u.user_id  as buyer_id,u.join_date,ifnull(s.cs,0) as orders_in_2019
from Users u
left join
(select buyer_id,count(order_date) cs
from Orders
where year(order_date) = 2019
group by buyer_id ) s
on u.user_id = s.buyer_id

1280. 学生们参加各科测试的次数

题型:表a×表b的所有可能,再结合表c的数量
解答:cross join的使用
from a cross join b left join c on a.列= c.列 and b.列= c.列
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

SELECT a.student_id, a.student_name, b.subject_name, COUNT(e.subject_name) AS attended_exams
FROM Students a CROSS JOIN Subjects b
    LEFT JOIN Examinations e ON a.student_id = e.student_id AND b.subject_name = e.subject_name
GROUP BY a.student_id, b.subject_name
ORDER BY a.student_id, b.subject_name

1174. 即时食物配送 II

题型:1,满足某种要求的占比 2, 删选出列A中不同种类的列B最早/小的记录
解题:1,打标签if(条件,1,0) 2,窗口函数排序 ,or 用min()
在这里插入图片描述

select round(sum(r1)/count(1)*100,2) as immediate_percentage
from 
(select *,if(order_date=customer_pref_delivery_date,1,0) as r1,
rank()over(partition by customer_id order by order_date ) as r2
 from Delivery) a
where r2=1

585. 2016年的投资

题型:要输出的记录满足: 列A值不唯一(与其他行有相同的),列B和列C的值唯一(B和C不能和其他记录完全相同)
思路:1,自连接,2,group by和having
解题1:把列A值不唯一的id值筛选出来,where id in (select distinct id from 啊a1 join a2 on a1.列A = a2.列A and a1.id = a2.id) 同理处理列B和列C

解法2:用group by 和count一起
where 列A in (select 列A from 表 group by 列A having count(*)>1)
列B和列C用concat连接起来

题目:TIV_2015列不唯一,LAT 和LON列一起不能和其他行重合。计算满足这样的条件中TIV_2016列求和

解法1中,left join 后on 条件1 and 条件2 会报错,而写成下面两种不会
原因在之前讲过,join 表1 和表2后,筛选条件放在on后面和where后面的区别

select round(sum(TIV_2016),2) as TIV_2016
from insurance
where
PID in
(select distinct a.PID
from insurance a join insurance b on a.TIV_2015 = b.TIV_2015 and a.PID !=b.PID) 
and
PID NOT in
(select distinct a.PID
from insurance a join insurance b on a.LAT = b.LAT and a.PID !=b.PID and a.LON = b.LON) 
select round(sum(TIV_2016),2) as TIV_2016
from insurance
where
PID in
(select distinct a.PID
from insurance a  left join insurance b on a.TIV_2015 = b.TIV_2015 where  a.PID !=b.PID) 
and
PID NOT in
(select distinct a.PID
from insurance a left join insurance b on a.LAT = b.LAT and a.PID !=b.PID where a.LON = b.LON) 
select round(sum(TIV_2016),2) as TIV_2016
from insurance
where
TIV_2015 in
(select TIV_2015
from insurance group by TIV_2015 having count(*)>1) 
and
concat(LAT, LON) in
(select concat(LAT, LON)
from insurance group by LAT, LON having count(*)=1) 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值