根据以往的MySQL使用经验总结了一些常用模型。
一、 “最”值问题
- 全局最值:使用聚合函数如
max、min
- 组中最值:在1的基础上搭配
group by
- 组间最值:
- 法一:在2的基础上搭配
having
,使用some/any/all
实现组的比较 - 法二: 在2的基础上使用子查询
- 法一:在2的基础上搭配
where 的筛选粒度为每一条记录,过滤行;having的筛选粒度为每一组,过滤组
二、排序问题
- 全局排序:
- 法一:
order by a, b
- 法二:使用开窗函数,
rank() over(partition by … order by …)
- 法三:自联结生成笛卡尔积,通过
where
实现字段值筛选,借助group by、count
获得排名列
- 法一:
- 组内排序(不聚合):
group by
搭配开窗函数,同上 - 前n问题:
- 法一:在开窗函数基础上比较
rank
值 - 法二:在 笛卡尔积基础上比较
having count(col) <=n
值
- 法一:在开窗函数基础上比较
三、连续问题
- 连续n次问题:n表错位联结,行满足 id,id+1,id+2…同时满足该行对应的n个表的值相等(where)
- 连续n次>值:在1基础上选取
- 连续n次>值>关系:在1基础上使用where
四、重复问题
- 去除全局重复值:
select distinct x
- 去除组内重复值:
count distinct y
五、比较问题
- 组比较:
having
搭配搭配聚合函数 - 行比较:联结后使用
where
- 行与组的比较:
- 法一:聚合后与表联结,然后使用
where
,可用 - 法二:聚合后放入
where
子查询中 - 法三:直接使用开窗函数,然后进行同行比较,开窗函数需要建立新列
- 法一:聚合后与表联结,然后使用
六、分组问题
- 查询多种聚合值:直接通过普通聚合函数实现
- 需要查询多种聚合值,同时每种聚合值还需要组内筛选:在查询的聚合函数中添加条件(嵌套子查询或
case when
) - 查询一种聚合值:直接使用聚合函数或在此基础上用
having
过滤组