Leetcode:197
join的妙用
一开始看到题目没反应过来直接用join就可以,还以为要用内置函数,怀疑这不是简单题,后面发现只是题意没读清楚,也可能是出题人语文不好(不是
题目是这样的:
编写一个 SQL 查询,来查找与之前(昨天的)日期相比温度更高的所有日期的 id 。
返回结果 不要求顺序 。
表结构
查询结果
解法如下:
select a.id
from
Weather a
join
Weather b
on a.Temperature >b.Temperature
AND datediff(a.recordDate,b.recordDate)=1
在一张表中查询比较值时,直接用join条件进行表的内连接就可以查询出结果。
此处顺便补充时间间隔函数datediff()
时间间隔函数在HQL中用的较多
Leetcode 262
图片.png
图片.png
题目:
写一段 SQL 语句查出"2013-10-01" 至 "2013-10-03" 期间非禁止用户(乘客和司机都必须未被禁止)的取消率。非禁止用户即 Banned 为 No 的用户,禁止用户即 Banned 为 Yes 的用户。
取消率的计算方式如下:(被司机或乘客取消的非禁止用户生成的订单数量) / (非禁止用户生成的订单总数)。
返回结果表中的数据可以按任意顺序组织。其中取消率 Cancellation Rate 需要四舍五入保留两位小数。
第一次解答代码
#复杂而又不灵活的第一次错误代码
select a.Request_at as Day, Round(b.cnt2/a.cnt1,2) as 'Cancellation Rate'
from
(
select m.Request_at,m.Client_Id,m.Status,count(*) as cnt1
from Trips m
join
Users n1
on m.Client_Id = n1.Users_Id
join
Users n2
on m.Driver_Id = n2.Users_Id
where n1.Banned ='No'
and n2.Banned ='No'
group by Request_at
) a
join
(
select Request_at,
count(case
when Status='completed' then null
when Status='cancelled_by_driver' then Client_Id
when Status='cancelled_by_client' then Client_Id
end
) as cnt2
from Trips
where Client_Id!=2 #一开始甚至想偷懒直接设置客户ID不等于禁止的
group by Request_at
) b
on a.Request_at = b.Request_at
where a.Request_at BETWEEN '2013-10-01' AND '2013-10-03'
group by a.Request_at
一开始解的时候是边写边思考逻辑,于是同一个join写了两次才把题解出来,但是这种做法很消耗性能,因此思考怎么把需要计数的条件在同一个join里查询出来,失败多次(不通过就很不甘心啊可恶)图片.png
于是求助评论区看到了使用if()函数的解法,解法较为简洁,参考下来代码如下:
正确代码
select m.Request_at as Day,
Round(count(if(Status !="completed",Status,null))/count(Status),2) as 'Cancellation Rate'
from Trips m
join
Users n1
on m.Client_Id = n1.Users_Id
join
Users n2
on m.Driver_Id = n2.Users_Id
where n1.Banned ='No'
and n2.Banned ='No'
and m.Request_at BETWEEN '2013-10-01' AND '2013-10-03'
group by m.Request_at
此处补充一下Mysql中if()函数的使用