热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

分组获取最大N条记录的优化方案及新年祝福

探讨如何从数据库中按分组获取最大N条记录的方法,并分享新年祝福。本文提供多种解决方案,适用于不同数据库系统,如MySQL、Oracle等。

在2009年的最后一天,我迎来了新的一颗星,也借此机会祝大家新年快乐!为了庆祝这一时刻,我们来探讨一个技术问题:如何从数据库中按分组获取最大N条记录。由于技术版面无法散分,特此征集解决方案。



假设我们有一个表t2,其结构如下:



CREATE TABLE t2 (
id INT PRIMARY KEY,
gid CHAR(1),
col1 INT,
col2 INT
) ENGINE=MyISAM;


插入一些示例数据:



INSERT INTO t2 VALUES 
(1,'A',31,6), (2,'B',25,83), (3,'C',76,21), (4,'D',63,56), (5,'E',3,17),
(6,'A',29,97), (7,'B',88,63), (8,'C',16,22), (9,'D',25,43), (10,'E',45,28),
(11,'A',2,78), (12,'B',30,79), (13,'C',96,73), (14,'D',37,40), (15,'E',14,86),
(16,'A',32,67), (17,'B',84,38), (18,'C',27,9), (19,'D',31,21), (20,'E',80,63),
(21,'A',89,9), (22,'B',15,22), (23,'C',46,84), (24,'D',54,79), (25,'E',85,64),
(26,'A',87,13), (27,'B',40,45), (28,'C',34,90), (29,'D',63,8), (30,'E',66,40),
(31,'A',83,49), (32,'B',4,90), (33,'C',81,7), (34,'D',11,12), (35,'E',85,10),
(36,'A',39,75), (37,'B',22,39), (38,'C',76,67), (39,'D',20,11), (40,'E',81,36);


我们希望实现以下结果:



N=1: 每组取col2最大的一条记录








































id gid col1 col2
6 A 29 97
15 E 14 86
24 D 54 79
28 C 34 90
32 B 4 90


N=3: 每组取col2最大的三条记录




































































































id gid col1 col2
6 A 29 97
11 A 2 78
36 A 39 75
32 B 4 90
2 B 25 83
12 B 30 79
28 C 34 90
23 C 46 84
13 C 96 73
24 D 54 79
4 D 63 56
9 D 25 43
15 E 14 86
25 E 85 64
20 E 80 63


注:

1)不限数据库类型,但请说明所使用的版本,例如 Oracle Database 10g 10.2, MySQL 5.1.33。

2)不限方法,可以使用SQL语句或存储过程。



解决方案



方法一:使用LEFT JOIN和GROUP BY



SELECT a.id, a.gid, a.col1, a.col2 FROM t2 a
LEFT JOIN t2 b ON a.gid = b.gid AND a.col2 <= b.col2
GROUP BY a.id, a.gid, a.col1, a.col2
HAVING COUNT(b.id) <= 3
ORDER BY a.gid, a.col2 DESC;


方法二:使用子查询



SELECT a.id, a.gid, a.col1, a.col2 FROM t2 a
WHERE 3 >= (
SELECT COUNT(*) FROM t2 b
WHERE a.gid = b.gid AND a.col2 <= b.col2
)
ORDER BY a.gid, a.col2 DESC;


方法三:使用窗口函数(适用于SQL Server 2005及以上版本)



WITH RankedRecords AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY gid ORDER BY col2 DESC) AS rn
FROM t2
)
SELECT id, gid, col1, col2
FROM RankedRecords
WHERE rn <= 3
ORDER BY gid, col2 DESC;


方法四:使用APPLY



SELECT DISTINCT b.*
FROM t2 a
CROSS APPLY (
SELECT TOP(3) *
FROM t2
WHERE a.gid = gid
ORDER BY col2 DESC
) AS b;


恭喜各位技术人员,希望这些解决方案对您有所帮助!


推荐阅读
  • 本文介绍 SQL Server 的基本概念和操作,涵盖系统数据库、常用数据类型、表的创建及增删改查等基础操作。通过实例帮助读者快速上手 SQL Server 数据库管理。 ... [详细]
  • 本文详细介绍如何利用已搭建的LAMP(Linux、Apache、MySQL、PHP)环境,快速创建一个基于WordPress的内容管理系统(CMS)。WordPress是一款流行的开源博客平台,适用于个人或小型团队使用。 ... [详细]
  • 通过Web界面管理Linux日志的解决方案
    本指南介绍了一种利用rsyslog、MariaDB和LogAnalyzer搭建集中式日志管理平台的方法,使用户可以通过Web界面查看和分析Linux系统的日志记录。此方案不仅适用于服务器环境,还提供了详细的步骤来确保系统的稳定性和安全性。 ... [详细]
  • 20100423:Fixes:更新批处理,以兼容WIN7。第一次系统地玩QT,于是诞生了此预备式:【QT版本4.6.0&#x ... [详细]
  • 方法:1 配置数据库basediros.path.abspath(os.path.dirname(__file__))  #获取当前文件的绝对路径appFlask(__name__ ... [详细]
  • 本文详细介绍了优化DB2数据库性能的多种方法,涵盖统计信息更新、缓冲池调整、日志缓冲区配置、应用程序堆大小设置、排序堆参数调整、代理程序管理、锁机制优化、活动应用程序限制、页清除程序配置、I/O服务器数量设定以及编入组提交数调整等方面。通过这些技术手段,可以显著提升数据库的运行效率和响应速度。 ... [详细]
  • 主调|大侠_重温C++ ... [详细]
  • 本文档介绍了如何在Visual Studio 2010环境下,利用C#语言连接SQL Server 2008数据库,并实现基本的数据操作,如增删改查等功能。通过构建一个面向对象的数据库工具类,简化了数据库操作流程。 ... [详细]
  • 如何在SQL Server 2008中通过Profiler跟踪特定数据库及获取客户端信息
    本文介绍如何利用SQL Server Profiler工具来监控特定数据库的操作,并获取执行这些操作的客户端计算机名和账户名。步骤包括创建新的跟踪、配置跟踪属性以及设置列筛选器以精确过滤数据。 ... [详细]
  • 使用Pandas高效读取SQL脚本中的数据
    本文详细介绍了如何利用Pandas直接读取和解析SQL脚本,提供了一种高效的数据处理方法。该方法适用于各种数据库导出的SQL脚本,并且能够显著提升数据导入的速度和效率。 ... [详细]
  • 深入理解T-SQL中的NULL与三值逻辑
    本文探讨了SQL Server中的三值逻辑,解释了谓词计算结果为TRUE、FALSE和UNKNOWN的规则。通过具体示例,详细说明了如何正确处理NULL值,并探讨了在不同约束条件下的行为。 ... [详细]
  • Netflix利用Druid实现高效实时数据分析
    本文探讨了全球领先的在线娱乐公司Netflix如何通过采用Apache Druid,实现了高效的数据采集、处理和实时分析,从而显著提升了用户体验和业务决策的准确性。文章详细介绍了Netflix在系统架构、数据摄取、管理和查询方面的实践,并展示了Druid在大规模数据处理中的卓越性能。 ... [详细]
  • 目录一、salt-job管理#job存放数据目录#缓存时间设置#Others二、returns模块配置job数据入库#配置returns返回值信息#mysql安全设置#创建模块相关 ... [详细]
  • 本文详细介绍了如何在Linux系统中创建和管理DB2数据库,包括用户切换、数据库创建、错误处理、连接与断开、表空间和缓冲池的创建,以及用户权限管理和数据导入导出等操作。 ... [详细]
  • 解决Hive操作无响应问题:drop table和create table的处理方法
    本文详细介绍了在Hive中执行drop table和create table命令时遇到无响应的情况,并提供了完整的解决方案。通过调整MySQL字符集编码,确保Hive数据库与MySQL之间的兼容性,从而有效解决问题。 ... [详细]
author-avatar
阁下贵姓
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有