当前位置:网站首页>Sql分组查询后取每组的前N条记录
Sql分组查询后取每组的前N条记录
2020-11-09 10:51:00 【osc_um3gbrdm】
目录
一、背景
最近,在开发中遇到个功能需求。系统有个资讯查询模块,要求资讯按照卡片形式展示。如下图:
按照项目组展示卡片,每个项目组展示阅读量最多的TOP2。
需求解析:按照项目组分组,然后取每组阅读量最多的前2条。
二、实战解析
基于Mysql数据库
表定义
1、项目组:team
id |
主键 |
name |
项目组名称 |
2、资讯表:info
id |
主键 |
team_id |
项目组id |
title |
资讯名称 |
pageviews |
浏览量 |
content |
资讯内容 |
info表数据如下图:
我们先预习下Select基础知识
书写顺序:
select *columns*
from *tables*
where *predicae1*
group by *columns*
having *predicae1*
order by *columns*
limit *start*, *offset*;
执行顺序:
from *tables*
where *predicae1*
group by *columns*
having *predicae1*
select *columns*
order by *columns*
limit *start*, *offset*;
count(字段名) # 返回表中该字段总共有多少条记录
DISTINCT 字段名 # 过滤字段中的重复记录
第一步:先找出资讯表中阅读量的前二名
info资讯表自关联
SELECT a.*
FROM info a
WHERE (
SELECT count(DISTINCT b.pageviews)
FROM info b
WHERE a.pageviews < b.pageviews AND a.team_id= b.team_id
) < 2 ;
乍一看不好理解,下面举例说明
举个例子:
当阅读量pageviews a = b = [1,2,3,4]
a.pageviews = 1,b.pageviews 可以取值 [2,3,4],count(DISTINCT b.pageviews) = 3
a.pageviews = 2,b.pageviews 可以取值 [3,4],count(DISTINCT b.pageviews) = 2 # 有2条,即第三名
a.pageviews = 3,b.pageviews 可以取值 [4],count(DISTINCT b.pageviews) = 1 # 有1条,即第二名
a.pageviews = 4,b.pageviews 可以取值 [],count(DISTINCT b.pageviews) = 0 # 有0条,即最大 第一名
count(DISTINCT b.pageviews) 代表有几个比这条值大
a.team_id= b.team_id 自关联条件,约等于分组
所以前二名 等价于 count(DISTINCT e2.Salary) < 2 ,所以 a.pageviews 可取值为 3、4,即集合前 2 高
第二步:再把表 team和表 info连接
SELECT a.id, t.NAME, a.team_id, a.pageviews
FROM info a
LEFT JOIN team t ON a.team_id = t.id
WHERE (
SELECT count(DISTINCT b.pageviews)
FROM info b
WHERE a.pageviews < b.pageviews AND a.team_id= b.team_id) < 2
ORDER BY a.team_id, a.pageviews desc
结果如下图:
还有一种好理解的方式:
分组GROUP BY + HAVING,这种方式可以一步一步方便调试结果
SELECT a.id, t.NAME, a.team_id, a.pageviews, COUNT( DISTINCT b.pageviews )
FROM info a
LEFT JOIN info b ON ( a.pageviews < b.pageviews AND a.team_id = b.team_id )
LEFT JOIN team t ON a.team_id = t.id
GROUP BY a.id, t.NAME, a.team_id, a.pageviews
HAVING COUNT( DISTINCT b.pageviews ) < 2
ORDER BY a.team_id, a.pageviews DESC
问题:如果出现阅读数相同的情况,就裂开了。
举例说明:
当阅读量pageviews a = b = [1,2,2,4]
a.pageviews = 1,b.pageviews 可以取值 [2,2,4],count(DISTINCT b.pageviews) = 3
a.pageviews = 2,b.pageviews 可以取值 [4],count(DISTINCT b.pageviews) = 1 # 有1条,即并列第二名
a.pageviews = 2,b.pageviews 可以取值 [4],count(DISTINCT b.pageviews) = 1 # 有1条,即第二名
a.pageviews = 4,b.pageviews 可以取值 [],count(DISTINCT b.pageviews) = 0 # 有0条,即最大 第一名
count(DISTINCT e2.Salary) < 2 ,所以 a.pageviews 可取值为 2、2、4,即集合前 2 高,但是有三条数据
三、总结
需求转化:将分组求前几条,改为了自关联后,有几条数据比这条大
其实这个是类似LeetCode上难度为hard的一道数据库题目
参考:
版权声明
本文为[osc_um3gbrdm]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/4267090/blog/4708807
边栏推荐
- 2020,Android开发者打破寒冬的利器是什么?
- 亚马逊的无服务器总线EventBridge支持事件溯源 - AWS
- 14. Introduction to kubenetes
- WordPress Import 上传的文件尺寸超过php.ini中定义的upload_max_filesize值--&gt;解决方法。
- 日志分析工具 - GoAccess
- Teacher Liang's small class
- How to reduce the resource consumption of istio agent through sidecar custom resource
- File queue in Bifrost (1)
- How does FC game console work?
- 商品管理系统——商品新增本地保存实现部分
猜你喜欢
RabbitMQ脑裂问题解决方案调查
File queue in Bifrost (1)
Have you ever thought about why the transaction and refund have to be split into different tables
Rainbow sorting | Dutch flag problem
无法启动此程序,因为计算机中丢失 MSVCP120.dll。尝试安装该程序以解决此问题
日志分析工具 - GoAccess
Adding OpenGL form to MFC dialog
Introduction to nmon
LTM理解及配置笔记记录
Capture bubbles? Is browser a fish?
随机推荐
作业2020.11.7-8
App crashed inexplicably. At first, it thought it was the case of the name in the header. Finally, it was found that it was the fault of the container!
EasyNTS上云网关设备在雪亮工程项目中的实战应用
1450. Number of students doing homework at a given time
A few lines of code can easily transfer traceid across systems, so you don't have to worry about losing the log!
无法启动此程序,因为计算机中丢失 MSVCP120.dll。尝试安装该程序以解决此问题
Deng Junhui's notes on data structure and algorithm learning - Chapter 9
The whole process of building a fully distributed cluster
Application of cloud gateway equipment on easynts in Xueliang project
2 normal mode
Rainbow sorting | Dutch flag problem
Dark网站的后端为什么选择F#? - darklang
服务网格仍然很难 - cncf
失业日志 11月5日
搭建全分布式集群全过程
Review of API knowledge
商品管理系统——整合仓库服务以及获取仓库列表
【QT】子类化QThread实现多线程
Initial installation of linx7.5
2. Introduction to computer hardware