题型:分组计数,并列第一的多个类别都输出
解答:order by后limit 1 只能输出一个类别
用count(1) >= all(select count(1) from 表 group by 列A)
select project_id
from Project
group by project_id
order by count(project_id) desc
limit 1
any()和all()函数
select project_id
from Project
group by project_id
having count(project_id) >= all(select count(1) from project group by project_id)
题型:对列A分组,每一个类型中,列B值最大的记录输出(可能有并列)
解答1:先max筛选出最大的,然后where筛选
where (列A,列B)in (select 列A,max(列B) from 表 group by 列A)
解法2:窗口函数dense_rank()排序,输出排序为1的
有两个表关联,可以先关联出来名为表t,后面用起来: with t as (…)
解法1:
# 链接2表
with t as
(select
a.project_id,
a.employee_id,
b.experience_years
from project a
join employee b
using(employee_id))
# 子查询匹配
select project_id,employee_id
from t
where (project_id, experience_years)
in
(select project_id, max(experience_years)
from t
group by 1)
解法2:
with t as
(select
a.project_id,
a.employee_id,
b.experience_years
from project a
join employee b
using(employee_id))
# 窗口函数
select project_id,employee_id
from
(select
project_id,
employee_id,
dense_rank() over(partition by project_id order by experience_years desc) as rnk
from t) tmp
where rnk =1
题型:表A与B连接,A中没有出现在B中的类别也要显示出来
解答:ifnull(语句,0)
易错点:
(1)容易忽略销量为0的书籍
(2)使用左链接,但是限制"近一年“使用了where字段,导致销量为null依然被忽略 --条件写在on里而不在where里
(3)having条件忘记is null,导致销量为null被忽略 ----ifnull()函数
select b.book_id,b.name
from books b left join orders o on o.book_id=b.book_id and dispatch_date >= '2018-06-23'
where b.available_from <='2019-05-23'
group by b.book_id
having ifnull(sum(quantity), 0)<10
题型:根据列A分组,每组类别中列C最大,列B最小的行记录输出
解答:窗口函数在这种排序问题中是一个很好的解法,别忘
select student_id,course_id,grade
from
(select *,
rank() over(partition by student_id order by grade desc,course_id asc) rk
from Enrollments) a
where rk=1
order by student_id
窗口函数总结:
<窗口函数> over (partition by <分组列名> order by <排序列名>)
rank() : 阶梯排序-前两个是并列的1,接下来就是第3名
dense_rank(): 连续排序-前两个是并列的1,接下来就是第2名
row_number(): 不会出现重复的排序
题型:见题目
解答:一步一步解就好,业务的平均次数先求出来—表t,大于平均次数—打标签k,次数至少两次–sum(k)>=2
with t as
(select event_type,avg(occurences ) as avgo
from Events e
group by event_type)
select business_id
from
(select e.business_id,e.event_type,e.occurences,if(e.occurences>t.avgo,,0) as k
from Events e left join t on e.event_type =t.event_type
) a
group by business_id
having sum(k)>=2