目录:
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
语句会更加简单