Leetcode SQL精选题(十)

113 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

46.关于rank()窗口做减法

select

log_id,

rank() over(order by log_id) -log as grp    #错误

from logs

select

min(log_id) start_id,

max(log_id) end_id

from

(

    select

log_id,

rank() over(order by log_id) as grp

from logs

)kk


group by kk.log_id - grp        #必须在外面,而且必须大减小,否则会报错什么bigint出问题的情况

order by min(log_id)

47.连接连接再连接

select s1.student_id, s1.student_name, s2.subject_name, count(e.subject_name) attended_exams


from Students s1

join Subjects s2

left join

Examinations e        #做了笛卡尔积之后还能再连接一次



on s1.student_id=e.student_id and s2.subject_name=e.subject_name

group by s1.student_id, s2.subject_name

order by s1.student_id, s2.subject_name

48.这也是连接的一个妙用:不断往上找领导

Image.png

select distinct e1.employee_id

from Employees e1,Employees e2, Employees e3

where e1.manager_id=e2.employee_id and e2.manager_id=e3.employee_id

and e3.manager_id=1 and e1.employee_id !=1

49.统计妙用:

(

select spend_date,user_id,sum(amount) as amount,

if(count(*)=1,platform,both) as platform        #如果有两个平台都有那就是both,如果没有平台也是both

from Spending

group by spend_date,user_id

)

50.mysql中时间最好还是做diff,如果直接相减可能会导致意想不到的后果

51.leetcode1225题

在一个函数中还可以做窗口,相当于压缩着写了

# Write your MySQL query statement below


select state as period_state,min(dt) as start_date,max(dt) as end_date

from

(

select

*,

#获得到所有的时间差,其语义为:从某一时间点开始

#因为有成功失败之分且数据都是连续的,同时即使有后续紧接上去的也会成功地切分出来

subdate(dt,row_number() over(partition by state order by dt)) as dif

# dt-row_number() over(partition by state order by dt) as dif  #不行

#mysql中时间最好还是做diff,如果直接相减可能会导致意想不到的后果

from

(

select fail_date as dt ,'failed' as state from failed

union all

select *,'succeeded' from succeeded

)a2

where dt>='2019-01-01' and dt<='2019-12-31'

)t2

group by state,dif

order by dt

52.有了窗口函数中分组,就不需要再别的变量上再做group by了

select

gender,day,sum(score_points) over(partition by gender order by day asc) as total

from scores

order by gender,day