Leetcode--SQL刷题(1194-1270)

1194. 锦标赛优胜者
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
题目中有一个翻译错误,当得分相同时应该是id小的获胜。
本题的关键是得到一个有player_id,group_id,score 组成的初始化表格。

# 自己的方法:得到初始化表格,想想哪不对?
select player_id,group_id, ifnull(m1.first_score,0)+ifnull(m2.second_score,0) score
from players p  left join matches m1
on p.player_id=m1.first_player
left join matches m2
on p.player_id=m2.second_player


# 方法1 不对,还没找到哪儿错(确定是获得初始表格代码还是不对)
 select group_id,player_id
 from
    (select group_id,player_id, CASE WHEN @id=group_id THEN @cnt:=@cnt+1
                                        WHEN @id:=group_id THEN @cnt:=1 end cnt
        from
            (select player_id,max(group_id) group_id, sum(ifnull(m1.first_score,0)+ifnull(m2.second_score,0)) score
            from players p  left join matches m1
            on p.player_id=m1.first_player
            left join matches m2
            on p.player_id=m2.second_player
            GROUP by player_id) t1,(select @id:=0, @cnt:=0) t2 
        order by group_id,score DESC, player_id)  t3 
WHERE cnt=1

# 正确的获得初始化表格的方法:不要left join两个表格,使用or 选定多个连表条件
select player_id,max(group_id) group_id, SUM(CASE when p.player_id=m.first_player then first_score
                                                  when p.player_id=m.second_player then second_score end) score
from players p  left join matches m
on p.player_id=m.first_player or p.player_id=m.second_player
GROUP by player_id
order by player_id



# 方法2  待优化
SELECT a.group_id, a.player_id
FROM (
	SELECT a.group_id, a.player_id, CASE WHEN @preCol = group_id THEN @rank := @rank + 1
			                             ELSE @rank := 1 END AS rk, @preCol := group_id
	FROM (
		SELECT player_id, MAX(group_id) AS group_id, SUM(CASE WHEN a.player_id = b.first_player THEN b.first_score
				                                              WHEN a.player_id = b.second_player THEN b.second_score
				                                              ELSE 0 END) AS allScore
		FROM Players a
		LEFT JOIN Matches b
		ON a.player_id = b.first_player OR a.player_id = b.second_player
		GROUP BY a.player_id) a, (SELECT @preCol := NULL, @rank := 0) r
	ORDER BY group_id, allScore DESC, player_id
) a
WHERE a.rk = 1

1204. Last Person to Fit in the Elevator 最后一个进入电梯的人
在这里插入图片描述
在这里插入图片描述
题目重点:turn是进入电梯的顺序。

# 自己的方法 0.9296
select person_name
from
    (select person_name, @sum_weight:=@sum_weight+weight sum_weight
    from queue q,(select @sum_weight:=0) t
    order by turn) t2 
where sum_weight<=1000
order by sum_weight desc
limit 1

1205. 每月交易II

这是一个多数据源的问题,学习思路(首先合并数据源)
在这里插入图片描述
在这里插入图片描述

# 超棒的逻辑 0.9126
SELECT date_format(a.trans_date, '%Y-%m') AS month, a.country, COUNT(CASE WHEN state = 'approved' THEN 1 ELSE NULL END) AS approved_count, 
                                                               SUM(CASE WHEN state = 'approved' THEN amount ELSE 0 END) AS approved_amount, 
                                                               COUNT(CASE WHEN state IS NULL THEN 1 ELSE NULL END) AS chargeback_count, 
                                                               SUM(CASE WHEN state IS NULL THEN amount ELSE 0 END) AS chargeback_amount
FROM (
	SELECT *
	FROM Transactions
	UNION ALL
	SELECT a.trans_id AS id, b.country, NULL, b.amount, a.trans_date
	FROM Chargebacks a
	JOIN Transactions b ON a.trans_id = b.id) a
WHERE a.state != 'declined' or a.state is null
GROUP BY a.country, date_format(a.trans_date, '%Y-%m') 

1212. Team Scores in Football Tournament
这道题可以说是1194题的精华部分的升级版~
注意得分规则
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

# 自己的方法 应该不错 0.9535
SELECT team_id, MAX(team_name) AS team_name, SUM(CASE WHEN team_id = host_team THEN host_goals
				                                      WHEN team_id = guest_team THEN guest_goals 
				                                      ELSE 0 END) AS num_points
FROM teams a
LEFT JOIN 
    (SELECT host_team,guest_team, case when host_goals > guest_goals then 3
                                    when host_goals = guest_goals then 1
                                    ELSE 0 end host_goals,
                                case when host_goals > guest_goals then 0
                                    when host_goals = guest_goals then 1
                                    ELSE 3 end guest_goals
    FROM Matches) b
ON a.team_id = b.host_team OR a.team_id = b.guest_team
GROUP BY a.team_id
order by num_points desc,team_id

1225. 报告系统状态的连续日期

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
有一个提示很重要:最后结果按照start_date排序。

# 自己的方法,以后尽量不要利用case在函数中,做赋值操作。还是单独写出来,有时候会报错。 0.6962
select 'failed' period_state, min(fail_date) start_date, max(fail_date) end_date
from
    (select fail_date, case when datediff(fail_date,@pre_date) = 1 then @cnt:=@cnt
                            else @cnt:=@cnt+1 end cnt, @pre_date := fail_date
    from failed, (select @pre_date:=null, @cnt:=0) t
    where fail_date between '2019-01-01' and '2019-12-31') t1 
group by cnt

union all

select 'succeeded' period_state, min(success_date) start_date, max(success_date) end_date
from
    (select success_date, case when datediff(success_date,@pre_date) = 1 then @cnt:=@cnt
                               else @cnt:=@cnt+1 end cnt, @pre_date := success_date
    from succeeded, (select @pre_date:=null, @cnt:=0) t
    where success_date between '2019-01-01' and '2019-12-31') t2 
group by cnt

order by start_date


# 方法2:一开始就合并数据源,而不是合并结果。 0.6456
SELECT flag AS period_state, MIN(ds) AS "start_date", MAX(ds) AS "end_date"
FROM (
	SELECT a.ds, CASE WHEN datediff(a.ds, @preCol) = 1 AND @preFlag = flag THEN @groupId
			          ELSE @groupId := @groupId + 1 END AS groupId, @preCol := a.ds, @preFlag := a.flag, a.flag
	FROM (
		SELECT fail_date AS ds, 'failed' AS flag
		FROM Failed
		UNION ALL
		SELECT success_date AS ds, 'succeeded' AS flag
		FROM Succeeded) a, (SELECT @preCol := NULL, @preFlag := NULL, @groupId := 0) s

	WHERE ds between '2019-01-01' AND  '2019-12-31') a

GROUP BY groupId
ORDER by start_date

1241. 每个帖子的评论数
这是一道简单题 但是感觉自己写的有点复杂了
在这里插入图片描述
在这里插入图片描述

# 自己的方法 0.91
select a.sub_id post_id, ifnull(count(parent_id),0) number_of_comments
from
    (select distinct sub_id
    from submissions
    where parent_id is null) a
left join
    (select distinct sub_id,parent_id
    from submissions
    where parent_id is not null) b
on a.sub_id=b.parent_id
group by a.sub_id
order by post_id


# 方法2 0.6651
SELECT
	post_id,
	COUNT( DISTINCT S2.sub_id ) AS number_of_comments 
FROM
	( SELECT DISTINCT sub_id AS post_id FROM Submissions WHERE parent_id IS NULL ) S1
LEFT JOIN Submissions S2 
ON S1.post_id = S2.parent_id 
GROUP BY S1.post_id

1251. Average Selling Price
在这里插入图片描述
在这里插入图片描述

# 法1
select p.product_id, round(sum(price*units)/sum(units),2) average_price
from
    prices p
join
    (select distinct a.* from unitssold a) u 
on p.product_id=u.product_id and u.purchase_date between start_date and end_date
group by p.product_id

# 法2 直接 join不去重 也可以通过
select p.product_id, round(sum(price*units)/sum(units),2) average_price
from
    prices p
join
    unitssold u 
on p.product_id=u.product_id and u.purchase_date between start_date and end_date
group by p.product_id

1270. All People Report to the Given Manager
在这里插入图片描述在这里插入图片描述
简单说一下本题的要求:找到直接或间接给老板汇报工作的员工。

SELECT employee_id EMPLOYEE_ID 
FROM employees
WHERE employee_id not in 
    (select employee_id from employees
    where manager_id in
        (select employee_id from employees
        where manager_id in
            (select employee_id from employees
            where manager_id in
                (select employee_id 
                from employees
                where employee_id=manager_id and employee_id != 1))))
and employee_id != 1
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值