热门标签 | 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中的索引机制,包括索引的基本概念、优势与劣势、分类及其实现原理,并详细介绍了索引的使用场景和优化技巧。通过具体示例,帮助读者更好地理解和应用索引以提升数据库性能。 ... [详细]
  • 利用存储过程构建年度日历表的详细指南
    本文将介绍如何使用SQL存储过程创建一个完整的年度日历表。通过实例演示,帮助读者掌握存储过程的应用技巧,并提供详细的代码解析和执行步骤。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
  • 本文详细介绍了如何通过多种编程语言(如PHP、JSP)实现网站与MySQL数据库的连接,包括创建数据库、表的基本操作,以及数据的读取和写入方法。 ... [详细]
  • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
    本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
  • 根据最新发布的《互联网人才趋势报告》,尽管大量IT从业者已转向Python开发,但随着人工智能和大数据领域的迅猛发展,仍存在巨大的人才缺口。本文将详细介绍如何使用Python编写一个简单的爬虫程序,并提供完整的代码示例。 ... [详细]
  • 本文详细介绍了 MySQL 中 LAST_INSERT_ID() 函数的使用方法及其工作原理,包括如何获取最后一个插入记录的自增 ID、多行插入时的行为以及在不同客户端环境下的表现。 ... [详细]
  • 本文探讨了MariaDB在当前数据库市场中的地位和挑战,分析其可能面临的困境,并提出了对未来发展的几点看法。 ... [详细]
  • 本文探讨了在Oracle数据库中,动态SQL语句的执行及其对事务管理的影响,特别是关于回滚操作的有效性。重点讨论了一个具体场景:将预警短信从当前表迁移到历史表时遇到的字段长度不匹配问题及相应的异常处理。 ... [详细]
  • 本文详细介绍如何利用已搭建的LAMP(Linux、Apache、MySQL、PHP)环境,快速创建一个基于WordPress的内容管理系统(CMS)。WordPress是一款流行的开源博客平台,适用于个人或小型团队使用。 ... [详细]
  • 本文探讨了使用C#在SQL Server和Access数据库中批量插入多条数据的性能差异。通过具体代码示例,详细分析了两种数据库的执行效率,并提供了优化建议。 ... [详细]
  • 本文详细介绍了中央电视台电影频道的节目预告,并通过专业工具分析了其加载方式,确保用户能够获取最准确的电视节目信息。 ... [详细]
  • 深入理解Redis的数据结构与对象系统
    本文详细探讨了Redis中的数据结构和对象系统的实现,包括字符串、列表、集合、哈希表和有序集合等五种核心对象类型,以及它们所使用的底层数据结构。通过分析源码和相关文献,帮助读者更好地理解Redis的设计原理。 ... [详细]
  • 使用Pandas高效读取SQL脚本中的数据
    本文详细介绍了如何利用Pandas直接读取和解析SQL脚本,提供了一种高效的数据处理方法。该方法适用于各种数据库导出的SQL脚本,并且能够显著提升数据导入的速度和效率。 ... [详细]
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社区 版权所有