3.📅
- [177. 第N高的薪水]
考察内容:创建函数!
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INTBEGINdeclare m INT;set m=N-1;RETURN (# Write your MySQL query statement below.select ifnull((select distinct Salary from Employee as E order by Salary desc limit m,1),null));ENDCREATE FUNCTION getNthHighestSalary(N INT) RETURNS INTBEGINset n = N-1;RETURN (# Write your MySQL query statement below.select ifnull((select distinct Salary getNthHighestSalaryfrom Employeeorder by Salary desclimit n, 1), null));END#top AnswerCREATE FUNCTION getNthHighestSalary(N INT) RETURNS INTBEGINSET N = N-1;RETURN (# Write your MySQL query statement below.SELECTsalaryFROMemployeeGROUP BYsalaryORDER BYsalary DESCLIMIT N, 1);END
- [178. 分数排名]
如果两个分数相同,则两个分数排名(Rank)相同。请注意,平分后的下一个名次应该是下一个连续的整数值。换句话说,名次之间不应该有“间隔”。
知识点考察:窗口函数 over?
# Write your MySQL query statement belowselect Score, dense_rank() over(order by Score desc) as 'Rank'from Scoresorder by Score desc;#可以理解select distinct a.Num as ConsecutiveNumsfrom Logs as a,Logs as b,Logs as cwhere a.Num=b.Num and b.Num=c.Num and a.id=b.id-1 and b.id=c.id-1;
3.31
- [181 连续出现的数字]
```sql
Write your MySQL query statement below
select distinct l1.num as ConsecutiveNums from logs l1 ,logs l2, logs l3 where
l1.id = l2.id-1 and l2.id = l3.id-1 and l1.num= l2.num and l2.num = l3.num
top answer
SELECT DISTINCT l1.Num AS ConsecutiveNums FROM Logs AS l1 INNER JOIN Logs AS l2 ON l1.Id + 1 = l2.Id AND l1.Num = l2.Num INNER JOIN Logs AS l3 ON l1.Id + 2 = l3.Id AND l1.Num = l3.Num
- [184 部门工资最高的员工]解题思路:group by + in!!!```sqlSELECTDepartment.name AS 'Department',Employee.name AS 'Employee',SalaryFROMEmployeeJOINDepartment ON Employee.DepartmentId = Department.IdWHERE(Employee.DepartmentId , Salary) IN( SELECTDepartmentId, MAX(Salary)FROMEmployeeGROUP BY DepartmentId)# 使用窗口函数跑一下select SELECTd.name AS 'Department',e.name AS 'Employee',SalaryFROM (select *,rank_over()(partition by departmentid ,order by salary desc)as 'rank' from employee) e left joindepartment don e.departmentid = d.id and e.rank = 1# 窗口函数——答案select t2.Name Department, t1.Name Employee, t1.Salary Salary from(select *, rank() over(partition by DepartmentId order by Salary desc) as 'rk' from Employee) t1, Department t2where t1.rk = 1 and t1.DepartmentId = t2.Id;
- 534 游戏玩法三
解题思路:窗口函数 sum()over(partition by order by)
# Write your MySQL query statement belowselect player_id,event_date,sum(games_played) over (partition by player_id order by event_date )as 'games_played_so_far' from activity;
- 550 游戏玩法四
解题思路:计算两个日期距离的天数 datediff(a,b) = 1——a是晚,b是早
SELECTROUND(COUNT(DISTINCT a.player_id) / (SELECT COUNT(DISTINCT player_id) FROM Activity), 2) AS fractionFROMActivity AS aINNER JOIN (SELECTplayer_id, MIN(event_date) AS first_loginFROMActivityGROUP BYplayer_id) AS bON a.player_id = b.player_id AND DATEDIFF(a.event_date, b.first_login) = 1;# 使用round函数select round((selectcount(a1.player_id) cntfromActivity a1,(selectplayer_id,min(event_date) event_datefrom Activitygroup by player_id) a2wherea1.player_id = a2.player_id anddatediff(a1.event_date, a2.event_date) = 1) / count(distinct a.player_id), 2) fractionfrom Activity aselectround((select count(*) from Activity ainner join(select player_id,min(event_date) first_date from Activity group by player_id) as bon a.player_id=b.player_idwhere datediff(a.event_date,b.first_date)=1)/(select count(distinct player_id) from Activity),2)as fraction
- 570 至少有5名直接下属
解题思路:group by ;having count() ;in
select name from employeewhere id in(select managerid from employee group by managerid having count(managerid) >=5 )# top Answer ——添加别名可以提升检索速度?SELECT e1.NameFROM employee e1WHERE e1.Id IN(SELECT manageridFROM employeeGROUP BY manageridHAVING COUNT(ManagerId) >= 5)# 使用内连接 inner joinselect e1.name as Name from Employee as e1left join Employee as e2on e1.Id = e2. ManagerIdgroup by e1.Id having count(e2.ManagerId) >= 5
- 574 当选者
解题思路:(不存在并列)使用group by+order by desc limit1
select name from candidatewhere id = #注意该处不可以使用 in(select candidateid from vote group by candidateid# group by 不可以抛弃order by count(candidateid) desc limit 1)# top Answerselect namefrom votejoin candidate on vote.candidateid = candidate.idgroup by candidateidorder by count(candidateid) desclimit 1
- 578 查询回答率最高的问题
tip:组内频率
# Write your MySQL query statement belowselect question_id as survey_log from survey_loggroup by question_idorder by count(answer_id) desc limit 1# top Answer# Write your MySQL query statement belowselect question_id survey_logfrom survey_loggroup by question_idorder by avg(answer_id is not null) desclimit 1
- 580 统计各专业学生数量
解题思路:group by 执行顺序优先于 select + left join
# Write your MySQL query statement belowselect dept_name ,count(student_id) as student_number from department d left join student son d.dept_id = s.dept_idgroup by d.dept_idorder by count(student_id) desc# top Answer
- 626 交换座位
解题思路:交换数据
判断奇偶数 mod(id,2) = 1 奇数 = 0 为偶数
使用方法: case when then;if ;异或 1^1 = 0,0^1 = 1
# Write your MySQL query statement belowselect(casewhen mod(id,2) = 1 and id != (select max(id)from seat)then id+1# 该位置只能使用 select语句 不可以使用count(distinct ID) or max(id)when mod(id,2) = 0 then id-1else id end ) as id ,studentfrom seatorder by id asc# Write your MySQL query statement belowselect(casewhen mod(id, 2) = 1 and id != (select max(id) from seat) then id + 1when mod(id, 2) = 0 then id - 1else id end) as id,studentfrom seatorder by id asc作者:jun-mo-xiao-21链接:https://leetcode-cn.com/problems/exchange-seats/solution/cha-xun-zi-ju-zhong-zhi-jie-shi-yong-case-whenlai-/来源:力扣(LeetCode)著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
- 1270 向公司CEO回报工作的所有员工
解题思路:总共三层,选出经理的层级就OK了
主要还是学会递归
#top Answer# Write your MySQL query statement belowselect e1.employee_idfrom Employees e1 left join Employees e2on e1.manager_id = e2.employee_idleft join Employees e3on e2.manager_id = e3.employee_idwhere e3.manager_id = 1 and e1.employee_id != 1
- 1501 可以放心投资的国家
解题思路:将phone_number 前缀提取-left join对应国家
到calls 表中联结两次,算时间!- 求均值
难点:提取phone_number 前缀:
country_code = LEFT(phone_number, 3)
# 我的答案——借鉴 一位老哥的思路 ——耗时1052 msselect c.name Country from country cright join (select id,left(phone_number,3) as c_d from person) tmpon c.country_code = tmp.c_dright join calls caon (ca.caller_id = tmp.id or ca.callee_id = tmp.id)#join条件语句可以使用or!group by c.country_codehaving avg(duration) > (select avg(duration) from calls)#top Answer ——耗时 731ms# Write your MySQL query statement belowSELECT c.name AS countryFROM Calls, Person, Country cWHERE (caller_id = id OR callee_id = id) AND country_code = LEFT(phone_number, 3)GROUP BY country_codeHAVING AVG(duration) > (SELECT AVG(duration) FROM Calls);
- 1098 小众书籍
解题思路 DATEDIFF(‘条件日期’,’变化日期’) 判定条件
注意:售卖1年的条件放在 left join on后面
如果放在where后面,1年中部分一本没卖的书籍直接被过滤了
注意left join和普通join 在on的后面跟条件的区别 left on+条件,只改变右边的值,无法改变左表的值,左表值仍然保留,没有where 的直接过滤作用 inner join 后的on + 条件,可以直接过滤条件 等同于where的作用
1、join on 和 where 选择不同,on是连接时,where是连接后筛选 2、dispatch_date条件位置的放置很关键,它必须放在on后面,如果where后面,则会将没有购买的信息过滤掉 3、如果将available_from放到on后面,则对left join 无影响,无法按条件去除信息
select b.book_id,name from books bleft join orders o on b.book_id = o.book_idand DATEDIFF('2019-06-23',dispatch_date) <=365where DATEDIFF('2019-05-23',available_from) > 30group by b.book_idhaving ifnull(sum(quantity),0) < 10
