Leetcode SQL会员题【吐血总结~~】第二天

目录:

612. 平面上的最近距离
613. 直线上的最近距离
614. 二级关注者
615. 平均工资:部门与公司比较
618. 学生地理信息报告
619. 只出现一次的最大数字
1068. 产品销售分析 I
1069. 产品销售分析 II
1070. 产品销售分析 III
1075. 项目员工 I
1076. 项目员工 II
1077. 项目员工 III
1082. 销售分析 I
1083. 销售分析 II


612. 平面上的最近距离

在这里插入图片描述
在这里插入图片描述

  • 源代码:
    select min(round(sqrt(pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2)), 2)) as shortest
    from point2d p1
    join point2d p2 
    on p1.x != p2.x or p1.y != p2.y
    
  • 思路:看到这个需求,应该很容易知道是自连接的,但是难在on后面的条件是什么,因为我们在进行自连接的时候不要和自己进行join,所以就判断两个x不相等或者两个y不相等,这样都不是自己。

613. 直线上的最近距离

在这里插入图片描述

  • 源代码:
    select min(abs(p1.x - p2.x)) as shortest
    from point p1
    join point p2
    on p1.x != p2.x;
    
  • 思路:和上面一题一样

614. 二级关注者

在这里插入图片描述

  • 源代码:
    select followee follower, count(*) num
    from follow
    where followee in (
        select follower
        from follow
    )
    group by followee
    order by follower
    
  • 思路:这个唯一需要注意的是 followee必须是出现在follower中的,题目中明确的很清楚,所以不会遗漏

615. 平均工资:部门与公司比较

在这里插入图片描述

  • 源代码:
    with cor_avg as (
        select substring(pay_date, 1, 7) date, avg(amount) cnt1
        from salary
        group by substring(pay_date, 1, 7)
    ),
    dep_avgt as (
        select substring(pay_date, 1, 7) date, department_id, avg(amount) cnt2
        from salary
        join employee
        on salary.employee_id = employee.employee_id
        group by substring(pay_date, 1, 7), department_id
    )
    select cor_avg.date pay_month, 
        department_id, 
        case 
            when cnt1 > cnt2 then 'lower' 
            when cnt1 = cnt2 then 'same' 
            else 'higher' end comparison
    from cor_avg
    join dep_avgt
    on cor_avg.date = dep_avgt.date
    
  • 思路:利用with tmp as ()的方式书写代码非常清晰明了,拿到题目就对需求进行拆分,很容易解决了

618. 学生地理信息报告**

在这里插入图片描述
在这里插入图片描述

  • 源代码:
    select
        max(case continent when 'America' then name else null end) America,
        max(case continent when  'Asia' then name else null end) Asia,
        max(case continent when 'Europe' then name else null end) Europe
    from (
        select * ,
        row_number() over(partition by continent order by name) rk
        from student
    )t
    group by rk;
    
  • 思路:跟行转列是差不多的,固定套路:max + case when,但是这个题目不同的是没有主键,并且按照姓名排序(难题)

619. 只出现一次的最大数字

在这里插入图片描述
在这里插入图片描述

  • 源代码:
    select max(num) as num
    from (
        select num
        from mynumbers
        group by num
        having count(*) = 1
    )t
    
  • 思路:分组聚合,比较简单

1068. 产品销售分析 I

在这里插入图片描述

  • 源代码:
    select product_name, year, price
    from sales
    join product 
    on sales.product_id = product.product_id;
    
  • 思路:就是一个简单的join

1069. 产品销售分析 II

在这里插入图片描述

  • 源代码:
    select product_id, sum(quantity) as total_quantity
    from sales
    group by product_id;
    
  • 思路:这就是分组聚合,没有复杂的逻辑

1070. 产品销售分析 III

在这里插入图片描述

  • 源代码:
    select product_id, year first_year, quantity, price
    from (
        select *, rank() over(partition by product_id order by year) rk
        from sales
    )t 
    where rk = 1;
    
  • 思路:rank()函数 开窗即可

1075. 项目员工 I

在这里插入图片描述

扫描二维码关注公众号,回复: 16758297 查看本文章

在这里插入图片描述

  • 源代码:
    select project_id, round(avg(experience_years), 2) as average_years
    from project
    join employee on project.employee_id = employee.employee_id
    group by project_id
    
  • 思路:先将两张表进行join,然后分组聚合

1076. 项目员工 II

在这里插入图片描述

  • 源代码:
    with tmp as (
        select project_id, count(*) cnt
        from project
        group by project_id
    )
    select project_id
    from tmp
    where cnt = (
        select max(cnt)
        from tmp
    )
    
  • 思路:本题的关键是利用with tmp as ()来建立临时表,因为tmp表在本题中会用到多次,所以一般我习惯性的先建立这个中间表

1076. 项目员工 III

在这里插入图片描述

  • 源代码:
    with tmp as (
        select project_id, project.employee_id, experience_years
        from project
        join employee on project.employee_id = employee.employee_id
    )
    select project_id, employee_id
    from tmp
    where (project_id, experience_years) in (
        select project_id, max(experience_years)
        from tmp
        group by project_id
    )
    
  • 思路:这个题目跟上面一题一样也需要建立一个中间表,就会对题目的难度简化很多

1076. 销售分析 I

在这里插入图片描述

  • 源代码:
    with tmp as (
        select seller_id, sum(price) cnt
        from sales
        group by seller_id
    )
    select seller_id
    from tmp
    where cnt = (
        select max(cnt)
        from tmp
    )
    
  • 思路:建立中间表

1083. 销售分析 II

在这里插入图片描述

  • 源代码:
select s.buyer_id
from sales s left join product p on p.product_id = s.product_id
group by buyer_id
having sum(product_name = 'S8') > 0 and sum(product_name = 'iPhone') = 0
  • 思路:其实这个题目也可以根据buyer_id,product_name来进行聚合,但是如果用having语句会更加简单

猜你喜欢

转载自blog.csdn.net/qq_42397330/article/details/123762102