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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章