Exercise部分竟然还有SQL题,不过都非常简单,可以说只要会SQL的基本都能答上。本身考核的Programming language有且只有SQL(PostgreSQL),不过SQL嘛,语法大同小异。
Exercise6 - SQL
SqlSum: Calculate sum of elements.
问题概述:统计表elements中整数类型列v的总和
解法概述:直接sum(v),朴实无华的解法
SELECT sum(v)
from elements
SqlEventsDelta: Compute the difference between the latest and the second latest value for each event type.
问题概述:表结构是有【event_type, value, time】三列,并且不存在重复的【event_type, time】记录,也就是记录中同一个event_type的多条记录,time一定不同。需要返回的,是对在表中至少存在两天记录的event_type,按event_type计算其在表中【最后一条记录】与【倒数第二条记录】之差。
解法概述:利用了row_number()函数,搭配group by函数实现了对每个event_type的最后一条记录与倒数第二条记录的选取。然后用了having语法筛除了只有一条记录的event_type。
select
event_type,
sum(case when rn=1 then value else 0 end) - sum(case when rn=2 then value else 0 end) as value
from
(SELECT event_type, value, row_number() over (partition by event_type order by time desc) as rn
from events
) tmp
group by event_type
having count(*)>1
;
SqlWorldCup: Given a list of matches in a group stage of the soccer World Cup, compute the number of points each team currently has.
问题概述:这次是一个需要跨表关联求解的问题,两张表teams和matches,teams记录每个队伍的team_id和team_name,matches记录所有的比赛记录,包括match_id,主客场team的id(host_team,guest_team)和比赛结果情况(host_goals,guest_goals)。
最终需要返回的,是根据所有matches结果,最终各个队的积分情况,并且需要返回的顺序,是按【积分降序+team_id升序】双条件进行排序后的结果。
解法概述:这里我们要对matches的结果进行一次拆分,用union all将主场队伍与客场队伍顺序拼接成同构的[team_id, score]两列的形式,然后作为副表与teams表中的id和name进行一次左关联,再group by team_id, team_name进行积分汇总,就能得到问题需求的结果。然后最后按照题目要求对结果进行order by排序,即可获得正确产出。
select
team_id
,team_name
,coalesce(sum(score),0) as num_points
from
(SELECT team_id, team_name
from teams
) t
left join
( select host_team,
case when host_goals>guest_goals then 3
when host_goals=guest_goals then 1
else 0
end as score
from matches
union all
select guest_team,
case when host_goals>guest_goals then 0
when host_goals=guest_goals then 1
else 3
end as score
from matches
) m
on t.team_id = m.host_team
group by team_id, team_name
order by num_points desc, team_id asc
;