【SQL高频练习带刷】day18:补充习题

题目一:查询球队积分

题目要求:

你希望在所有比赛之后计算所有球队的比分。积分奖励方式如下:

  • 如果球队赢了比赛(即比对手进更多的球),就得 3 分。
  • 如果双方打成平手(即,与对方得分相同),则得 1 分。
  • 如果球队输掉了比赛(例如,比对手少进球),就 不得分 。

编写解决方案,以找出每个队的 team_idteam_name 和 num_points

返回的结果根据 num_points 降序排序,如果有两队积分相同,那么这两队按 team_id  升序排序

1212. 查询球队积分 - 力扣(LeetCode)

表结构:

运行结果示例:

思路:

        我们首先创建一张临时表,使用case when 讨论各种情况,将所有球队的得分列举出来,再使用union all将主场球队的得分情况和客场球队的得分情况进行组合,得到一张完整的各个球队的得分表。再连接teams表获取球队的名字,并按照球队id和名称分组,计算得分总和(注意要对空值进行处理,使用ifnull()函数令空值为0)。

扫描二维码关注公众号,回复: 17472296 查看本文章

运行代码示例:

with temp as (
select host_team as team_id, case when host_goals > guest_goals then 3 when host_goals = guest_goals then 1 else 0 end as goals
from Matches
union all
select guest_team as team_id, case when host_goals < guest_goals then 3 when host_goals = guest_goals then 1 else 0 end as goals
from Matches
)


select team_id, team_name, ifnull(sum(goals) ,0) as num_points
from Teams
left join temp
using(team_id)
group by team_id,team_name
order by num_points desc, team_id

题目二:即时食物配送I

题目要求:

如果顾客期望的配送日期和下单日期相同,则该订单称为 「即时订单」,否则称为「计划订单」。

编写解决方案统计即时订单所占的百分比, 保留两位小数。

1173. 即时食物配送 I - 力扣(LeetCode)

表结构:

运行结果示例:

思路:

        用case when子句或者if else子句进行判断即可,对于符合“即时订单”定义的订单计数为1,否则计为0,计算总和即为即时订单的数量,再除以总数量即可。注意本题的结果要显示为百分数,因此要先将计算结果乘以100再使用round()函数保留小数。如果题目中要求显示为x%的形式,还要使用字符串拼接函数进行拼接。

运行代码示例:

select round(sum(if(order_date = customer_pref_delivery_date,1,0)) / count(*) *100,2) as immediate_percentage
from Delivery

题目三:苹果和橘子

题目要求:

编写解决方案报告每一天 苹果 和 桔子 销售的数目的差异.

返回的结果表, 按照格式为 ('YYYY-MM-DD') 的 sale_date 排序.

1445. 苹果和桔子 - 力扣(LeetCode)

表结构:

运行结果示例:

思路:

        本题同样是使用了if或case判断,根据时间进行分组,计算橘子和苹果的售卖总数,最后按照日期排序。

运行代码示例:

select sale_date,sum(if(fruit = 'apples', sold_num,0)) - sum(if(fruit = 'oranges', sold_num,0)) as diff
from Sales
group by sale_date
order by sale_date

题目四:两人之间的通话次数

题目要求:

编写解决方案,统计每一对用户 (person1, person2) 之间的通话次数和通话总时长,其中 person1 < person2 。

以 任意顺序 返回结果表。

1699. 两人之间的通话次数 - 力扣(LeetCode)

表结构:

运行结果示例:

思路:

        分别将通话双方作为person1和person2,用unoin all进行查询结果的合并,这样我们就得到了一张有所有通话记录且不区分主被动通话方的表格,但是每次通话都被计算了两遍。

        接下来我们在临时表中筛选出person1 < person2 的数据,同时也就完成了去除重复数据的操作,计算通话次数和时长总和即可。

运行代码示例:

with temp as (
    select from_id as person1, to_id as person2,duration
    from Calls
    union all
    select to_id as person1,from_id as person2,duration
    from Calls
)

select person1,person2,count(*) as call_count,sum(duration) as total_duration 
from temp
where person1 < person2
group by person1,person2

题目五:上个月播放的儿童适宜电影

题目要求:

编写解决方案, 报告在 2020 年 6 月份播放的儿童适宜电影的去重电影名.

返回的结果表单 没有顺序要求 .

1495. 上月播放的儿童适宜电影 - 力扣(LeetCode)

表结构:

运行结果示例:

思路:

        我们连接两张表,使用where语句将所需要判断的条件罗列出来进行筛选即可,注意要对查询结果去重。

运行代码示例:

select distinct title from Content c 
left join TVProgram t 
using(content_id)
where left(program_date,7) = '2020-06' and Kids_content ='Y' and content_type ='Movies'

猜你喜欢

转载自blog.csdn.net/Liu_y_xin/article/details/141898107