热门标签 | 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;


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


推荐阅读
  • MySQL索引详解与优化
    本文深入探讨了MySQL中的索引机制,包括索引的基本概念、优势与劣势、分类及其实现原理,并详细介绍了索引的使用场景和优化技巧。通过具体示例,帮助读者更好地理解和应用索引以提升数据库性能。 ... [详细]
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
  • 本文探讨了在Oracle数据库中,动态SQL语句的执行及其对事务管理的影响,特别是关于回滚操作的有效性。重点讨论了一个具体场景:将预警短信从当前表迁移到历史表时遇到的字段长度不匹配问题及相应的异常处理。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 利用存储过程构建年度日历表的详细指南
    本文将介绍如何使用SQL存储过程创建一个完整的年度日历表。通过实例演示,帮助读者掌握存储过程的应用技巧,并提供详细的代码解析和执行步骤。 ... [详细]
  • 本文介绍了如何通过 Maven 依赖引入 SQLiteJDBC 和 HikariCP 包,从而在 Java 应用中高效地连接和操作 SQLite 数据库。文章提供了详细的代码示例,并解释了每个步骤的实现细节。 ... [详细]
  • 本文介绍如何通过创建替代插入触发器,使对视图的插入操作能够正确更新相关的基本表。涉及的表包括:飞机(Aircraft)、员工(Employee)和认证(Certification)。 ... [详细]
  • 本文由瀚高PG实验室撰写,详细介绍了如何在PostgreSQL中创建、管理和删除模式。文章涵盖了创建模式的基本命令、public模式的特性、权限设置以及通过角色对象简化操作的方法。 ... [详细]
  • 本文详细介绍了 MySQL 中 LAST_INSERT_ID() 函数的使用方法及其工作原理,包括如何获取最后一个插入记录的自增 ID、多行插入时的行为以及在不同客户端环境下的表现。 ... [详细]
  • 探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ... [详细]
  • 使用Pandas高效读取SQL脚本中的数据
    本文详细介绍了如何利用Pandas直接读取和解析SQL脚本,提供了一种高效的数据处理方法。该方法适用于各种数据库导出的SQL脚本,并且能够显著提升数据导入的速度和效率。 ... [详细]
  • Windows服务与数据库交互问题解析
    本文探讨了在Windows 10(64位)环境下开发的Windows服务,旨在定期向本地MS SQL Server (v.11)插入记录。尽管服务已成功安装并运行,但记录并未正确插入。我们将详细分析可能的原因及解决方案。 ... [详细]
  • openGauss每日一练:第6天 - 模式的创建、修改与删除
    本篇笔记记录了openGauss数据库中关于模式(Schema)的创建、修改和删除操作。通过这些操作,用户可以更好地管理和控制数据库对象。实验环境为openGauss 2.0.0,并使用由墨天轮提供的线上环境。 ... [详细]
  • 本文详细探讨了JDBC(Java数据库连接)的内部机制,重点分析其作为服务提供者接口(SPI)框架的应用。通过类图和代码示例,展示了JDBC如何注册驱动程序、建立数据库连接以及执行SQL查询的过程。 ... [详细]
  • 本文探讨了MariaDB在当前数据库市场中的地位和挑战,分析其可能面临的困境,并提出了对未来发展的几点看法。 ... [详细]
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社区 版权所有