LeetCode 高频 SQL 50 题(进阶版)
2023-06-05 15:04:59 3 举报
AI智能生成
Leetcode sql
作者其他创作
大纲/内容
查询
1821. 寻找今年具有正收入的客户
select <br>customer_id<br>from Customers<br>where year = '2021' and revenue > 0;
183. 从不订购的客户
select<br>s.Name as 'Customers'<br>from Customers s<br>where s.Id not in (select o.CustomerId from Orders o)<br>;
1873. 计算特殊奖金
select <br>employee_id<br>,case when mod(employee_id,2) = 1 and substr(name,1,1) <> 'M' then salary else 0 end as bonus<br>from Employees<br>order by employee_id;
1398. 购买了产品 A 和产品 B 却没有购买产品 C 的顾客
way1:傻瓜写法
select <br> o.customer_id,c.customer_name<br>from Orders o left join Customers c using(customer_id)<br>where <br>o.customer_id in (select customer_id from Orders where product_name ='A')<br>AND o.customer_id in (select customer_id from Orders where product_name ='B')<br>AND o.customer_id NOT in (select customer_id from Orders where product_name ='C')<br>group by o.customer_id order by o.customer_id<br>
way2:having 写法
select <br>customer_id<br>,customer_name<br>from Orders join Customers using(customer_id)<br>group by customer_id<br>having sum(product_name='A') and sum(product_name='B') <br>AND not sum(product_name='C')<br>order by customer_id<br>
way3:正则表达式
1112. 每位学生的最高成绩
way1:开窗函数
select<br>student_id,min(course_id) as course_id,grade<br>from (<br> select <br>student_id,course_id,grade<br>,dense_rank() over(partition by student_id order by grade desc) as rn <br>from Enrollments<br>) a where rn =1<br>group by student_id,grade<br>order by student_id;<br>
way2:子查询
# 子查询<br>select <br> student_id,min(course_id) as course_id<br> ,grade<br>from Enrollments<br>where (student_id,grade) in (<br> select <br> student_id,max(grade)<br> from Enrollments <br> group by student_id<br>)<br>group by student_id,grade<br>order by student_id<br>
连接
175. 组合两个表
select<br>p.firstName<br>,p.lastName<br>,a.city<br>,a.state<br>from Person p left join Address a on p.personId = a.personId<br>;
1607. 没有卖出的卖家
# 写一个SQL语句, 报告所有在2020年度没有任何卖出的卖家的名字.<br># 返回结果按照 seller_name 升序排列.<br><br>select <br>s.seller_name as 'seller_name'<br>from Seller s <br>where s.seller_id not in (<br> select seller_id from Orders where year(sale_date) = '2020'<br>)<br>order by s.seller_name;<br>
select <br>s.seller_name<br>from Seller s <br>left join Orders o on s.seller_id = o.seller_id and year(o.sale_date) = '2020'<br>where o.seller_id is null<br>order by s.seller_name<br>;
1407. 排名靠前的旅行者
select <br>u.name,ifnull(sum(r.distance),0) as travelled_distance<br>from Users u left join Rides r<br>on u.id = r.user_id<br>group by r.user_id<br>order by travelled_distance desc,u.name asc;
-- 性能低、拆解<br>select <br>u.name,ifnull(travelled_distance,0) as travelled_distance<br>from Users u left join <br>(select user_id,sum(distance) as travelled_distance<br>from Rides group by user_id) r<br>on u.id = r.user_id<br>group by r.user_id<br>order by travelled_distance desc,u.name asc;
607. 销售员
select <br>name<br>from SalesPerson<br>where sales_id not in (<br> select sales_id<br> from Orders o left join Company c on o.com_id = c.com_id<br> where c.name = 'red'<br>);
1440. 计算布尔表达式的值
# Write your MySQL query statement below<br>SELECT E.left_operand AS left_operand,<br> E.operator AS operator,<br> E.right_operand AS right_operand,<br> -- ② 再判断这一行要比的大小<br> ( CASE <br> -- ③ 若 这一组的正确答案 和 E表中对这一组的判断 一样,就返回 true<br> WHEN V1.value > V2.value AND E.operator = '>' THEN 'true'<br> WHEN V1.value = V2.value AND E.operator = '=' THEN 'true'<br> WHEN V1.value < V2.value AND E.operator = '<' THEN 'true'<br> -- ④ 其他回答则是 false<br> ELSE 'false'<br> END<br> ) AS value<br>FROM Expressions E<br>-- ① 先把 x、y 的值填进表中(以增广的形式)<br>LEFT JOIN Variables V1<br> ON E.left_operand = V1.name<br>LEFT JOIN Variables V2<br> ON E.right_operand = V2.name<br>
1212. 查询球队积分
select <br> team_id,team_name,ifnull(sum(num_points),0) as num_points <br>from (<br> ## 主场<br>select<br> t.team_id<br>,t.team_name <br>,case <br> when host_goals > guest_goals then 3<br> when host_goals = guest_goals then 1<br> when host_goals < guest_goals then 0<br> end as num_points <br>from Matches m <br>right join Teams t <br>on host_team = team_id<br>union all3<br>## 客场 <br>select<br> t.team_id<br>,t.team_name <br>,case <br> when guest_goals > host_goals then 3<br> when guest_goals = host_goals then 1<br> when guest_goals < host_goals then 0<br> end as num_points<br>from Matches m <br>right join Teams t <br>on guest_team = team_id<br>) a<br>group by team_id,team_id<br>order by num_points desc,team_id asc
select <br> team_id,team_name,ifnull(sum(num_points),0) as num_points <br>from (<br> ## 主场<br>select<br><br>host_team as team<br>,case <br> when host_goals > guest_goals then 3<br> when host_goals = guest_goals then 1<br> when host_goals < guest_goals then 0<br> end as num_points <br>from Matches m <br>union all<br>## 客场 <br>select<br>guest_team as team<br>,case <br> when guest_goals > host_goals then 3<br> when guest_goals = host_goals then 1<br> when guest_goals < host_goals then 0<br> end as num_points<br>from Matches m <br><br>) a<br>right join Teams t <br>on team = t.team_id<br>group by t.team_id,t.team_name<br>order by num_points desc,team_id asc
聚合函数
1890. 2020年最后一次登录
select <br>user_id<br>,max(time_stamp) as last_stamp<br>from Logins<br>where year(time_stamp) = '2020'<br>group by user_id
511. 游戏玩法分析 I
select<br> player_id<br>,min(event_date) as first_login<br>from Activity<br>group by player_id;
1571. 仓库经理
select<br>w.name as 'WAREHOUSE_NAME'<br>,sum(w.units * (Width * Length * Height)) as 'VOLUME'<br>from Warehouse w,Products pp where w.product_id = pp.product_id<br>group by w.name;
select<br>w.name as 'WAREHOUSE_NAME'<br>,sum(w.units * (Width * Length * Height)) as 'VOLUME'<br>from Warehouse w left join Products pp on w.product_id = pp.product_id<br>group by w.name;
586. 订单最多的客户
way1:开窗函数
select<br>a.customer_number<br>from (<br> select customer_number<br> ,dense_rank() over(order by count(order_number) desc) as rn <br> from Orders<br> group by customer_number<br>) a<br>where a.rn = '1';
way2:官方解法
select<br>customer_number<br>from Orders<br>group by customer_number<br>order by count(*) desc<br>limit 1;
1741. 查找每个员工花费的总时间
编写一个SQL查询以计算每位员工每天在办公室花费的总时间(以分钟为单位)。 <br>请注意,在一天之内,同一员工是可以多次进入和离开办公室的。 <br>在办公室里一次进出所花费的时间为out_time 减去 in_time。<br><br>
select<br>event_day as day<br>,emp_id<br>,sum(out_time-in_time) as total_time<br>from Employees<br>group by event_day,emp_id
1173. 即时食物配送 I
如果顾客期望的配送日期和下单日期相同,则该订单称为 「即时订单」,否则称为「计划订单」。<br><br>写一条 SQL 查询语句获取即时订单所占的百分比, 保留两位小数。<br><br>查询结果如下所示。<br>
way1
select <br>round(ifnull((<br> (sum(case when order_date = customer_pref_delivery_date then 1 else 0 end))<br> /(sum(1)) * 100<br>),0),2) as immediate_percentage<br>from Delivery;
way2
select <br>round(<br>sum(order_date = customer_pref_delivery_date)<br> /count(*) * 100<br>,2) as immediate_percentage<br>from Delivery<br>;
way3
select<br>round(<br> (select count(*) from Delivery where order_date = customer_pref_delivery_date)<br> /(select count(*) from Delivery)<br> * 100<br> ,2) as immediate_percentage;
1445. 苹果和桔子
way1
select <br>sale_date <br>,(sum(case when fruit = 'apples' then sold_num else 0 end)<br>-sum(case when fruit = 'oranges' then sold_num else 0 end)) as diff<br>from Sales<br>group by sale_date<br>order by sale_date
way2
select <br>sale_date <br>,(sum(case when fruit = 'apples' then sold_num else -sold_num end)) as diff<br>from Sales<br>group by sale_date<br>order by sale_date
way3:自连接
select<br>s1.sale_date <br>,(s2.sold_num-s1.sold_num) as diff<br>from Sales s1, Sales s2 <br>where s1.sale_date =s2.sale_date <br>and s1.fruit != s2.fruit <br>group by s1.sale_date
select<br>s1.sale_date <br>,(s2.sold_num-s1.sold_num) as diff<br>from Sales s1 inner join Sales s2 <br>on s1.sale_date =s2.sale_date <br>where s1.fruit != s2.fruit <br>group by s1.sale_date
1699. 两人之间的通话次数
## way1 位置调换<br>select <br> case when from_id > to_id then to_id else from_id end as person1<br> ,case when from_id > to_id then from_id else to_id end as person2<br> ,count(duration) as call_count <br> ,sum(duration) as total_duration <br><br>from Calls<br>group by person1,person2
排序和分组
1587. 银行账户概要 II
select<br>u.name<br>,sum(amount) as balance<br>from Transactions t left join Users u on t.account = u.account<br>group by t.account<br>having balance > 10000;
select <br>*from (select<br>u.name<br>,sum(amount) as balance<br>from Transactions t left join Users u on t.account = u.account<br>group by t.account) a<br>where a.balance >10000<br>;<br>
182. 查找重复的电子邮箱
way1:having
select<br>email as Email<br>from Person<br>where email is not null<br>group by email<br>having count(Email) >1;
way1:where
select<br>email<br>from (select<br>email as Email<br>,count(email) as num<br>from Person<br>where email is not null<br>group by email) a<br>where a.num >1<br>;
1050. 合作过至少三次的演员和导演
way1:嵌套一层效率更高
select <br>actor_id,director_id from (select <br>actor_id,director_id<br>,count(timestamp) as cnt<br>from ActorDirector<br>group by actor_id,director_id<br>having cnt >= 3) a<br>;<br>
way2:基本解法
select <br>actor_id,director_id<br>from ActorDirector<br>group by actor_id,director_id<br>having count(*) >= 3;<br>
way3:where
select<br>actor_id<br>,director_id<br>from (select<br>actor_id<br>,director_id<br>,count(timestamp) as cnt<br>from ActorDirector<br>group by actor_id<br>,director_id) a where a.cnt >=3<br>
1511. 消费者下单频率
select<br> o.customer_id<br> ,c.name<br>from Orders o left join Product p on o.product_id = p.product_id<br>left join Customers c on o.customer_id = c.customer_id<br>where order_date like '2020-07%' or order_date like '2020-06%'<br>group by o.customer_id,c.name<br>having sum(case when order_date like '2020-07%' then p.price*o.quantity else 0 end ) >= 100 <br>and sum(case when order_date like '2020-06%' then p.price*o.quantity else 0 end ) >= 100<br><br>
select<br> aa.customer_id<br> ,aa.name<br>from (<br> select<br> o.customer_id<br> ,c.name<br> ,sum(case when order_date like '2020-07%' then p.price*o.quantity else 0 end ) as july<br> ,sum(case when order_date like '2020-06%' then p.price*o.quantity else 0 end ) as june<br>from Orders o left join Product p on o.product_id = p.product_id<br>left join Customers c on o.customer_id = c.customer_id<br>where order_date like '2020-07%' or order_date like '2020-06%'<br>group by o.customer_id,c.name<br>) aa<br>where aa.july >= 100 and aa.june >= 100;<br>
select c.customer_id,c.name<br>from Customers c<br>inner join (<br> select customer_id<br> from Orders o <br> left join Product p <br> on o.product_id=p.product_id<br> where order_date like '2020-06%'<br> group by o.customer_id<br> having sum(p.price*quantity)>=100<br>) as m6<br>on c.customer_id=m6.customer_id<br>inner join (<br> select customer_id,order_id<br> from Orders d <br> left join Product t<br> on d.product_id=t.product_id<br> where order_date like '2020-07%'<br> group by d.customer_id<br> having sum(t.price*quantity)>=100<br>) as m7<br>on c.customer_id=m7.customer_id
1693. 每天的领导和合伙人
select <br>date_id,make_name<br>,count(distinct lead_id) as unique_leads<br>,count(distinct partner_id) as unique_partners<br>from DailySales<br>group by date_id,make_name
1495. 上月播放的儿童适宜电影<br>
select <br> distinct c.title as title<br>from TVProgram t left join Content c using(content_id)<br>where c.content_type = 'Movies' and DATE_FORMAT(t.program_date,'%Y-%m') = '2020-06'<br>and Kids_content = 'Y'<br>;
考察10种“2020年6月”的表达
DATE_FORMAT(t.program_date,'%Y-%m') = '2020-06'
t.program_date like '2020-06%'
t.program_date regexp '^2020-06'
and year(t.program_date) = '2020' and month(t.program_date) ='06'
left(t.program_date,7) ='2020-06'
and extract(YEAR_MONTH from t.program_date) ='202006'
1501. 可以放心投资的国家
with aa as (select <br>caller_id as id<br>,duration<br>from Calls c1<br>union all<br>select <br>callee_id as id<br>,duration<br>from Calls c2)<br>,bb as (select <br>c.name as country <br>,p.id<br>from Person p <br>left join Country c on <br>substr(p.phone_number,1,3)=country_code)<br><br>select <br> bb.country<br>from aa left join bb using(id)<br>group by bb.country<br>having (sum(aa.duration)/count(*)) > (select sum(aa.duration)/count(*)from aa)
with aa as (select <br>caller_id as id<br>,duration<br>from Calls c1<br>union all<br>select <br>callee_id as id<br>,duration<br>from Calls c2)<br>,bb as (select <br>c.name as country <br>,p.id<br>from Person p <br>left join Country c on <br>substr(p.phone_number,1,3)=country_code)<br><br>select <br> bb.country<br>from aa left join bb using(id)<br>group by bb.country<br>having avg(duration) > (select avg(aa.duration) from aa)
高级查询和连接
603. 连续空余座位
way1:将两个表连接的结果是这两个表的 笛卡尔乘积
select<br>distinct a.seat_id<br>from Cinema a,Cinema b<br>where abs(a.seat_id-b.seat_id)=1 and a.free=1 and b.free = 1<br>order by a.seat_id;
way2:开窗函数
with aa as(<br> select seat_id,(seat_id - row_number() over()) as rn <br> from Cinema where free = '1'<br> order by seat_id<br>)<br>select <br>seat_id<br>from aa where rn in (<br> select rn<br> from aa <br> group by rn having count(*) >= 2<br>)<br>;
1795. 每个产品在不同商店的价格
way1:行转列(横表转竖表)
select<br>product_id<br>,'store1' as store<br>,store1 as price<br>from Products<br>where store1 is not null<br>union all<br>select<br>product_id<br>,'store2' as store<br>,store2 as price<br>from Products<br>where store2 is not null<br>union all<br>select<br>product_id<br>,'store3' as store<br>,store3 as price<br>from Products<br>where store3 is not null
613. 直线上的最近距离
select<br>min(abs(a.x-b.x)) as shortest<br>from point a,point b<br>where a.x != b.x;
SELECT<br> MIN(ABS(p1.x - p2.x)) AS shortest<br>FROM<br> point p1<br> JOIN<br> point p2 ON p1.x != p2.x<br>;<br>
1965. 丢失信息的雇员
way1:子查询
with aa as (<br> select employee_id from Employees<br> union all<br> select employee_id from Salaries<br>)<br>select <br>employee_id<br>from aa group by 1 having count(*) = 1 order by 1
way2:union all
select employee_id from Employees where employee_id not in (select employee_id from Salaries)<br> union all<br> select employee_id from Salaries where employee_id not in (select employee_id from Employees)<br> order by employee_id
1264. 页面推荐
SELECT DISTINCT page_id AS recommended_page<br>FROM Likes<br>WHERE user_id IN (<br> SELECT (<br> CASE<br> WHEN user1_id = 1 then user2_id<br> WHEN user2_id = 1 then user1_id<br> END<br> ) AS user_id<br> FROM Friendship<br> WHERE user1_id = 1 OR user2_id = 1<br>) AND page_id NOT IN (<br> SELECT page_id FROM Likes WHERE user_id = 1<br>)<br>
SELECT DISTINCT page_id AS recommended_page<br>FROM Likes<br>WHERE user_id IN (<br> SELECT user1_id AS user_id FROM Friendship WHERE user2_id = 1<br> UNION ALL<br> SELECT user2_id AS user_id FROM Friendship WHERE user1_id = 1<br>) AND page_id NOT IN (<br> SELECT page_id FROM Likes WHERE user_id = 1<br>)<br>
608. 树节点
way1:
# Write your MySQL query statement below<br>SELECT<br> id, 'Root' AS Type<br>FROM<br> tree<br>WHERE<br> p_id IS NULL<br><br>UNION<br><br>SELECT<br> id, 'Leaf' AS Type<br>FROM<br> tree<br>WHERE<br> id NOT IN (SELECT DISTINCT<br> p_id<br> FROM<br> tree<br> WHERE<br> p_id IS NOT NULL)<br> AND p_id IS NOT NULL<br><br>UNION<br><br>SELECT<br> id, 'Inner' AS Type<br>FROM<br> tree<br>WHERE<br> id IN (SELECT DISTINCT<br> p_id<br> FROM<br> tree<br> WHERE<br> p_id IS NOT NULL)<br> AND p_id IS NOT NULL<br>ORDER BY id;<br>
way2
SELECT<br> id AS `Id`,<br> CASE<br> WHEN tree.id = (SELECT atree.id FROM tree atree WHERE atree.p_id IS NULL)<br> THEN 'Root'<br> WHEN tree.id IN (SELECT atree.p_id FROM tree atree)<br> THEN 'Inner'<br> ELSE 'Leaf'<br> END AS Type<br>FROM<br> tree<br>ORDER BY `Id`<br>;<br><br>
way3
SELECT<br> atree.id,<br> IF(ISNULL(atree.p_id),<br> 'Root',<br> IF(atree.id IN (SELECT p_id FROM tree), 'Inner','Leaf')) Type<br>FROM<br> tree atree<br>ORDER BY atree.id<br><br>
534. 游戏玩法分析 III
way1:开窗函数
select <br>player_id<br>,event_date<br>,sum(games_played) over(partition by player_id order by event_date) as games_played_so_far<br>from Activity<br>
way2:自关联
select<br>a.player_id<br>,a.event_date<br>,sum(b.games_played) as games_played_so_far<br><br>from Activity a,Activity b<br>where a.player_id=b.player_id<br>and a.event_date>=b.event_date<br>group by a.player_id<br>,a.event_date<br>
1783. 大满贯数量
way1:行列转换
Wimbledon as id<br>from Championships a1<br>union all<br>select <br>Fr_open as id<br>from Championships a2<br>union all<br>select <br>US_open as id<br>from Championships a3<br>union all<br>select <br>Au_open as id<br>from Championships a4)<br><br>select <br>id as player_id<br>,bb.player_name<br>,count(id) as grand_slams_count<br>from aa inner join Players bb on aa.id = bb.player_id<br>group by id,bb.player_name<br>
way2:笛卡尔积
select<br>player_id<br>,player_name<br>,sum(<br> if(c.Wimbledon=p.player_id,1,0)+<br> if(c.Fr_open=p.player_id,1,0)+<br> if(c.US_open=p.player_id,1,0)+<br> if(c.Au_open=p.player_id,1,0)<br>) as grand_slams_count<br>from Players p ,Championships c<br>group by player_id,player_name<br>having grand_slams_count >0<br>
1747. 应该被禁止的 Leetflex 账户
way1:自连接
select <br> distinct a.account_id<br>from LogInfo a inner join LogInfo b<br>on a.account_id= b.account_id<br>and a.ip_address <> b.ip_address<br>and a.login between b.login and b.logout<br>
备注
a,b where
=
a inner join b on
子查询
1350. 院系无效的学生
select <br>s.id,s.name<br>from Students s left join Departments d on s.department_id = d.id<br>where d.name is null;
select <br>s.id,s.name<br>from Students s <br>where s.department_id not in (<br> select id from Departments<br>);
1303. 求团队人数
way1
窗口函数
select<br>employee_id<br>,count(employee_id) over(partition by team_id) as team_size<br>from Employee<br>order by employee_id<br>;<br>
way2
自连接
select <br>a.employee_id,b.team_size<br>from Employee a,(select team_id<br>,count(team_id) as team_size<br>from Employee<br>group by team_id<br>order by team_id<br>) b<br>where a.team_id = b.team_id<br>order by a.employee_id<br>;
512. 游戏玩法分析 II
select player_id<br>,device_id<br>from Activity ac<br>where (ac.player_id,ac.event_date) in (select player_id,<br>min(event_date) as mi<br>from Activity<br>group by player_id<br>)
窗口函数
select <br>player_id,device_id<br>from (<br> select<br>player_id,device_id,<br>dense_rank() over(partition by player_id order by event_date asc) as rn<br>from Activity<br>) a where a.rn =1;
184. 部门工资最高的员工
way1:开窗函数
select <br>Department,Employee,Salary<br>from (select<br>d.name as Department<br>,e.name as Employee<br>,e.salary as Salary<br>,dense_rank() over(partition by e.departmentId order by e.salary desc) as rn <br>from Employee e left join Department d on e.departmentId = d.id<br>group by d.name<br>,e.name,e.salary<br>) aa<br>where rn = 1;<br>
way2:子查询
select <br> Department.name as Department<br>,Employee.name as Employee<br>,Employee.Salary<br> from Employee<br> left join Department on Employee.departmentId = Department.id<br> where (departmentId,salary) in (<br> select<br> departmentId<br>,max(salary) as salary<br>from Employee<br>group by departmentId<br> )<br>
1549. 每件商品的最新订单
way1:开窗函数
# Write your MySQL query statement below<br>select <br>product_name,product_id,order_id<br>,order_date<br>from (select <br>p.product_name<br>,s.product_id<br>,s.order_id<br>,s.order_date<br>,dense_rank() over(partition by s.product_id order by s.order_date desc) as rn <br>from Orders s left join Products p using(product_id)<br>) a<br>where rn =1 <br>order by product_name,product_id,order_id<br><br>
way1:子查询
select<br> p.product_name,o.product_id,o.order_id,o.order_date<br>from Orders o inner join Products P using(product_id)<br>where (o.product_id,o.order_date) in (<br> select<br> product_id,max(order_date)<br> from Orders group by product_id<br>)<br>order by p.product_name,o.product_id,o.order_id<br>
1532. 最近的三笔订单
way1:窗口函数
select <br> customer_name<br> ,customer_id<br> ,order_id<br> ,order_date<br>from (select<br>c.name as customer_name<br>,s.customer_id<br>,s.order_id<br>,s.order_date<br>,rank() over(partition by s.customer_id order by s.order_date desc ) as rn<br>from Orders s left join Customers c using(customer_id)<br>) a where rn <=3 <br>order by customer_name,customer_id,order_date desc<br>
1831. 每天的最大交易<br>
way1:开窗函数
select <br>transaction_id<br>from (<br> select<br>transaction_id<br>,dense_rank() over(partition by date_format(day,'%Y-%m-%d') order by amount desc) as rn <br>from Transactions<br>) a<br>where rn =1<br>order by transaction_id<br>
way2:子查询
select <br>transaction_id<br>from Transactions<br>where (date(day),amount) in (<br> select<br> date(day)<br> ,max(amount)<br> from Transactions<br> group by date(day)<br>)<br>order by transaction_id<br>
高级主题:窗口函数和公共表表达式(CTE)
1077. 项目员工 III
way1:开窗函数
select <br>project_id,employee_id<br>from (select<br>project_id<br>,employee_id<br>,dense_rank() over(partition by project_id order by experience_years desc) rn <br>from Project p left join Employee e using(employee_id)) a<br>where rn =1;<br><br>
way2:子查询
with aa as (<br> select <br> p.project_id<br> ,p.employee_id<br> ,e.name<br> ,e.experience_years<br> from Project p left join Employee e using(employee_id)<br>)<br>select<br> aa.project_id,aa.employee_id<br>from aa where (aa.project_id,aa.experience_years)<br>in (<br> select<br> project_id,max(experience_years)<br> from aa<br> group by project_id<br>)
1285. 找到连续区间的开始和结束数字
way1:开窗函数差值计算
select <br> min(log_id) as start_id <br>,max(log_id) as end_id <br>from (select <br> log_id<br>,row_number() over(order by log_id) as rn<br>,(log_id - row_number() over(order by log_id)) as diff<br>from Logs<br>) a<br>group by a.diff order by a.log_id<br>
1596. 每位顾客最经常订购的商品
way1:窗口函数
select <br> a.customer_id,a.product_id,b.product_name<br>from (<br> select<br>customer_id,product_id<br>,rank() over(partition by customer_id order by count(1) desc) as rn <br>from Orders<br>group by customer_id,product_id<br>) a left join Products b using(product_id)<br>where rn =1 and a.product_id = b.product_id;<br>
way2: 多表链接
1709. 访问日期之间最大的空档期
way1:开窗函数
## 开窗函数<br>select<br>user_id,max(diff_wind) as biggest_window<br>from (select<br>user_id,visit_date<br>,lead(visit_date,1,'2021-01-01') over(partition by user_id order by visit_date) as next_visit_date<br>,datediff((lead(visit_date,1,'2021-01-01') over(partition by user_id order by visit_date)),visit_date) as diff_wind<br>from UserVisits) aa<br>group by user_id<br><br>
way2:自关联
1270. 向公司CEO汇报工作的所有人<br>
way1:union all
SELECT DISTINCT employee_id FROM (<br> SELECT employee_id<br> FROM Employees WHERE manager_id = 1<br> UNION ALL<br> SELECT employee_id<br> FROM Employees WHERE manager_id IN (<br> SELECT employee_id FROM Employees WHERE manager_id = 1<br> )<br> UNION ALL<br> SELECT employee_id<br> FROM Employees WHERE manager_id IN (<br> SELECT employee_id FROM Employees WHERE manager_id IN (<br> SELECT employee_id FROM Employees WHERE manager_id = 1<br> )<br> )<br>) T WHERE employee_id != 1<br><br><br>
way2:join
SELECT e1.employee_id<br>FROM Employees e1<br>JOIN Employees e2 ON e1.manager_id = e2.employee_id<br>JOIN Employees e3 ON e2.manager_id = e3.employee_id<br>WHERE e1.employee_id != 1 AND e3.manager_id = 1<br><br>
1412. 查找成绩处于中游的学生<br>
way1:子查询写法
select student_id, student_name<br>from Student<br>where student_id in<br>(select distinct student_id from Exam)<br>and student_id not in<br>(<br> select student_id<br> from Exam where (exam_id, score) in<br> (select exam_id, max(score) socre<br> from Exam<br> group by exam_id)<br>)<br>and student_id not in<br>(<br> select student_id<br> from Exam where (exam_id, score) in<br> (select exam_id, min(score) socre<br> from Exam<br> group by exam_id)<br>)
select student_id, student_name <br>from Student<br>where (student_id, student_name) not in (<br> select s.student_id, s.student_name<br> from Student s left join Exam e on s.student_id = e.student_id<br> where (e.exam_id, e.score) in (<br> select exam_id, max(score) score<br> from Exam<br> group by exam_id<br> union all<br> select exam_id, min(score) score<br> from Exam<br> group by exam_id<br> ) or e.exam_id is null<br> group by s.student_id<br>)<br><br>
way2:开窗函数写法
select<br> a.student_id,s.student_name<br>from (<br> select <br> *<br> ,if(dense_rank() over(partition by exam_id order by score desc)=1,1,0) as ma_r<br> ,if(dense_rank() over(partition by exam_id order by score )=1,1,0) as mi_r<br>from Exam<br>) a left join Student s using(student_id)<br>group by a.student_id<br>having sum(a.ma_r) =0 and sum(a.mi_r) =0<br>order by a.student_id<br>
way3:开窗函数写法
select<br> a.student_id,s.student_name<br>from (<br> select <br> *<br> ,dense_rank() over(partition by exam_id order by score desc) as ma_r<br> ,dense_rank() over(partition by exam_id order by score ) as mi_r<br>from Exam<br>) a left join Student s using(student_id)<br>group by a.student_id<br>having min(a.ma_r) <>1 and min(a.mi_r) <>1<br>order by a.student_id
1767. 寻找没有被执行的任务对
way1:MYSQL RECURSIVE
with recursive table1 as (<br> select task_id, subtasks_count subtask_id from Tasks<br> union all<br> select task_id, subtask_id-1 from table1 where subtask_id > 1<br>)<br>select <br> task_id, <br> subtask_id<br>from table1<br>left join Executed E using(task_id, subtask_id)<br>where E.task_id is null
way2:
WITH recursive t(n) as --创建递归序列<br>(<br> SELECT 1<br> UNION<br> SELECT n+1 FROM t WHERE n<=19<br>)<br><br>SELECT task_id,n AS subtask_id <br>FROM Tasks,t<br>WHERE n<=subtasks_count --筛选出每个task_id可能的结果<br>AND (task_id,n) not in (SELECT * FROM Executed ) --剔除每个task_id已经有的结果<br>ORDER BY task_id
with recursive t as(<br> select 1 as n <br> union <br> select n+1 from t where n<=19<br>)<br><br>select task_id,n as subtask_id<br>from tasks,t<br>where n<=subtasks_count<br>and (task_id,n) not in (<br> select *<br> from executed<br>)
1225. 报告系统状态的连续日期
way1:
select type as period_state, min(date) as start_date, max(date) as end_date<br>from<br>(<br> select type, date, subdate(date,row_number()over(partition by type order by date)) as diff<br> from<br> (<br> select 'failed' as type, fail_date as date from Failed<br> union all<br> select 'succeeded' as type, success_date as date from Succeeded<br> ) a<br>)a<br>where date between '2019-01-01' and '2019-12-31'<br>group by type,diff<br>order by start_date<br>
way2
# Write your MySQL query statement below<br># 开窗函数 典型写法 2<br>select <br> aa.type as period_state<br> ,min(dt) as start_date<br> ,max(dt) as end_date<br>from (<br> select <br> a.*<br> ,row_number() over(partition by a.type order by dt) as an<br> ,row_number() over(order by dt) as rn<br>from (select<br>'failed' as type <br>,fail_date as dt<br>from Failed<br>union all<br>select<br>'succeeded' as type <br>,success_date as dt<br>from Succeeded) a<br>) aa<br>where year(aa.dt) = '2019'<br>group by aa.type,rn-an<br>order by start_date<br><br><br>
题型
简单:26道
中等:21道
困难:3道
0 条评论
下一页