一.集合
1.in是可以多字段使用
1112. 每位學生的最高成績
表:Enrollments
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| student_id | int |
| course_id | int |
| grade | int |
+---------------+---------+
(student_id, course_id) 是該表的主鍵。
編寫一個 SQL 查詢,查詢每位學生獲得的最高成績和它所對應的科目,若科目成績并列,取 course_id 最小的一門。查詢結果需按 student_id 增序進行排序。
查詢結果格式如下所示:
Enrollments 表:
+------------+-------------------+
| student_id | course_id | grade |
+------------+-----------+-------+
| 2 | 2 | 95 |
| 2 | 3 | 95 |
| 1 | 1 | 90 |
| 1 | 2 | 99 |
| 3 | 1 | 80 |
| 3 | 2 | 75 |
| 3 | 3 | 82 |
+------------+-----------+-------+
Result 表:
+------------+-------------------+
| student_id | course_id | grade |
+------------+-----------+-------+
| 1 | 2 | 99 |
| 2 | 2 | 95 |
| 3 | 3 | 82 |
+------------+-----------+-------+
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/highest-grade-for-each-student
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
# Write your MySQL query statement below
select en.student_id,Min(en.course_id ) course_id ,en.grade
from Enrollments en
where (en.student_id,en.grade) in(
select e.student_id,Max(e.grade) max_grade
from Enrollments e
group by e.student_id
)
group by en.student_id
order by en.student_id
2.采用exist邏輯比in更好理解
585. 2016年的投資
寫一個查詢語句,將 2016 年 (TIV_2016) 所有成功投資的金額加起來,保留 2 位小數。
對于一個投保人,他在 2016 年成功投資的條件是:
他在 2015 年的投保額 (TIV_2015) 至少跟一個其他投保人在 2015 年的投保額相同。
他所在的城市必須與其他投保人都不同(也就是說維度和經度不能跟其他任何一個投保人完全相同)。
輸入格式:
表 insurance 格式如下:
Column Name | Type |
---|---|
PID | INTEGER(11) |
TIV_2015 | NUMERIC(15,2) |
TIV_2016 | NUMERIC(15,2) |
LAT | NUMERIC(5,2) |
LON | NUMERIC(5,2) |
PID 字段是投保人的投保編號, TIV_2015 是該投保人在2015年的總投保金額, TIV_2016 是該投保人在2016年的投保金額, LAT 是投保人所在城市的維度, LON 是投保人所在城市的經度。
樣例輸入
PID | TIV_2015 | TIV_2016 | LAT | LON |
---|---|---|---|---|
1 | 10 | 5 | 10 | 10 |
2 | 20 | 20 | 20 | 20 |
3 | 10 | 30 | 20 | 20 |
4 | 10 | 40 | 40 | 40 |
樣例輸出
TIV_2016 |
---|
45.00 |
解釋
就如最后一個投保人,第一個投保人同時滿足兩個條件:
- 他在 2015 年的投保金額 TIV_2015 為 '10' ,與第三個和第四個投保人在 2015 年的投保金額相同。
- 他所在城市的經緯度是獨一無二的。
第二個投保人兩個條件都不滿足。他在 2015 年的投資 TIV_2015 與其他任何投保人都不相同。
且他所在城市的經緯度與第三個投保人相同。基于同樣的原因,第三個投保人投資失敗。
所以返回的結果是第一個投保人和最后一個投保人的 TIV_2016 之和,結果是 45 。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/investments-in-2016
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
select sum(a.TIV_2016) TIV_2016
from insurance a
where exists(
select *
from insurance b
where a.pid <> b.pid and a.TIV_2015 = b.TIV_2015
)
and not exists(
select *
from insurance c
where c.pid <> a.pid and c.lat = a.lat and a.lon = c.lon
)
二.行轉列
[這題用戶到排名分組和行轉列的兩種思路]
618. 學生地理信息報告
一所美國大學有來自亞洲、歐洲和美洲的學生,他們的地理信息存放在如下 student 表中。
name | continent |
---|---|
Jack | America |
Pascal | Europe |
Xi | Asia |
Jane | America |
寫一個查詢語句實現對大洲(continent)列的 透視表 操作,使得每個學生按照姓名的字母順序依次排列在對應的大洲下面。輸出的標題應依次為美洲(America)、亞洲(Asia)和歐洲(Europe)。數據保證來自美洲的學生不少于來自亞洲或者歐洲的學生。
對于樣例輸入,它的對應輸出是:
America | Asia | Europe |
---|---|---|
Jack | Xi | Pascal |
Jane |
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/students-report-by-geography
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
# Write your MySQL query statement below
select Max(case when s.continent='America' then s.name else NULL end) as America,
Max(case when s.continent='Asia' then s.name else NULL end) as Asia,
Max(case when s.continent='Europe' then s.name else NULL end) Europe
from
(select *,
@rk:=if(@pre=t.continent,@rk+1,1) as rk,
@pre:=t.continent as pre
from student t,(select @pre:=NULL,@rk:=0) t1
order by t.continent,t.name) s
group by s.rk
3.上下級
1270. 向公司CEO匯報工作的所有人
員工表:Employees
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| employee_id | int |
| employee_name | varchar |
| manager_id | int |
+---------------+---------+
employee_id 是這個表的主鍵。
這個表中每一行中,employee_id 表示職工的 ID,employee_name 表示職工的名字,manager_id 表示該職工匯報工作的直線經理。
這個公司 CEO 是 employee_id = 1 的人。
用 SQL 查詢出所有直接或間接向公司 CEO 匯報工作的職工的 employee_id 。
由于公司規模較小,經理之間的間接關系不超過 3 個經理。
可以以任何順序返回的結果,不需要去重。
查詢結果示例如下:
Employees table:
+-------------+---------------+------------+
| employee_id | employee_name | manager_id |
+-------------+---------------+------------+
| 1 | Boss | 1 |
| 3 | Alice | 3 |
| 2 | Bob | 1 |
| 4 | Daniel | 2 |
| 7 | Luis | 4 |
| 8 | Jhon | 3 |
| 9 | Angela | 8 |
| 77 | Robert | 1 |
+-------------+---------------+------------+
Result table:
+-------------+
| employee_id |
+-------------+
| 2 |
| 77 |
| 4 |
| 7 |
+-------------+
公司 CEO 的 employee_id 是 1.
employee_id 是 2 和 77 的職員直接匯報給公司 CEO。
employee_id 是 4 的職員間接匯報給公司 CEO 4 --> 2 --> 1 。
employee_id 是 7 的職員間接匯報給公司 CEO 7 --> 4 --> 2 --> 1 。
employee_id 是 3, 8 ,9 的職員不會直接或間接的匯報給公司 CEO。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/all-people-report-to-the-given-manager
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
# Write your MySQL query statement below
select distinct a.employee_id
from Employees a,Employees b,Employees c
where a.manager_id=b.employee_id and b.manager_id = c.employee_id and c.manager_id =1 and a.employee_id <> 1