当前位置:网站首页>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
边栏推荐
- 自然语言处理(NLP)路线图 - kdnuggets
- Deng Junhui's notes on data structure and algorithm learning - Chapter 9
- Log analysis tool - goaccess
- Common feature pyramid network FPN and its variants
- 2. Introduction to computer hardware
- 23张图,带你入门推荐系统
- [QT] subclass qthread to realize multithreading
- Principle analysis and performance tuning of elasticsearch
- EasyNTS上云网关设备在雪亮工程项目中的实战应用
- Commodity management system -- integrate warehouse services and obtain warehouse list
猜你喜欢
Three ways to operate tables in Apache iceberg
Finally, the python project is released as exe executable program process
A solution to the problem that color picker (palette) cannot use shortcut keys in sublime Text3 plug-in
1450. Number of students doing homework at a given time
Graph node classification and message passing
Adding OpenGL form to MFC dialog
EasyNTS上云网关设备在雪亮工程项目中的实战应用
JT-day09
图节点分类与消息传递 - 知乎
OSChina 周一乱弹 —— 程序媛的青春
随机推荐
ThinkPHP门面源码解析
Several rolling captions based on LabVIEW
2.计算机硬件简介
为什么我们不使用GraphQL? - Wundergraph
Deng Junhui's notes on data structure and algorithm learning - Chapter 9
How to do thread dump analysis in Windows Environment
Log analysis tool - goaccess
Review of API knowledge
2020,Android开发者打破寒冬的利器是什么?
1486. 数组异或操作
1.操作系统是干什么的?
结合阿里云 FC 谈谈我对 FaaS 的理解
range_sensor_layer
Mac 终端(terminal) oh-my-zsh+solarized配置
亚马逊的无服务器总线EventBridge支持事件溯源 - AWS
3.你知道计算机是如何启动的吗?
2 普通模式
日志分析工具 - GoAccess
Natural language processing (NLP) roadmap - KDnuggets
2 normal mode