热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

MySQL分组排序取前N条记录以及生成自动数字序列--groupby后limit外加rownumber_MySQL

同事提了一个需求,要求按照某列分组,然后将各组的前几条抽取出来。表结构CREATETABLE`total_freq_ctrl`(`time`int(10)unsignedNOTNULL,`machine`char(64)NOTNULL,`modu
同事提了一个需求,要求按照某列分组,然后将各组的前几条抽取出来。

表结构

CREATE TABLE `total_freq_ctrl` (
  `time` int(10) unsigned NOT NULL,
  `machine` char(64) NOT NULL,
  `module` char(32) NOT NULL,
  `total_flow` int(10) unsigned NOT NULL,
  `deny_flow` int(10) unsigned NOT NULL,
  PRIMARY KEY (`module`,`machine`,`time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
tudou@b2c.xiaomi.com

原sql

SELECT machine, deny_flow, total_flow, time FROM total_freq_ctrl A WHERE 1 > (SELECT COUNT(machine) FROM total_freq_ctrl WHERE machine = A.machine AND time > A.time) AND A.module = 'all' ORDER BY A.time desc;
只要将 1 改成N就变成取每组的前N条,因为我极其不喜欢子查询,就改就尝试改称join 的方式。

不过这里需要对所有数据进行排序才能确定每组的前N条,所以最佳优化也要全表扫描一次。

首先我要对表中数据进行排序,引入一个变量@row来做rownumber

set @row=0;set @mid='';SELECT module, machine, time, @row:=@row+1 rownum FROM total_freq_ctrl order by module,machine,time desc limit 10; 
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

+--------+---------------+------------+--------+
| module | machine       | time       | rownum |
+--------+---------------+------------+--------+
| all    | 10.201.20.181 | 1409640060 |      1 |
| all    | 10.201.20.181 | 1409640000 |      2 |
| all    | 10.201.20.181 | 1409639940 |      3 |
| all    | 10.201.20.181 | 1409639880 |      4 |
| all    | 10.201.20.97  | 1409640060 |      5 |
| all    | 10.201.20.97  | 1409640000 |      6 |
| all    | 10.201.20.97  | 1409639940 |      7 |
| all    | 10.201.20.97  | 1409639880 |      8 |
| all    | 10.201.20.98  | 1409640060 |      9 |
| all    | 10.201.20.98  | 1409640000 |     10 |
+--------+---------------+------------+--------+
rownumber已经出来了,再加一个@mid来进行分组
set @row=0;set @mid='';SELECT module, machine, time,case when @mid = machine then @row:=@row+1 else @row:=1 end rownum, @mid:=machine FROM total_freq_ctrl order by module,machine,time desc limit 20;
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

+--------+---------------+------------+--------+---------------+
| module | machine       | time       | rownum | @mid:=machine |
+--------+---------------+------------+--------+---------------+
| all    | 10.201.20.181 | 1409640180 |      1 | 10.201.20.181 |
| all    | 10.201.20.181 | 1409640120 |      2 | 10.201.20.181 |
| all    | 10.201.20.181 | 1409640060 |      3 | 10.201.20.181 |
| all    | 10.201.20.181 | 1409640000 |      4 | 10.201.20.181 |
| all    | 10.201.20.181 | 1409639940 |      5 | 10.201.20.181 |
| all    | 10.201.20.181 | 1409639880 |      6 | 10.201.20.181 |
| all    | 10.201.20.97  | 1409640180 |      1 | 10.201.20.97  |
| all    | 10.201.20.97  | 1409640120 |      2 | 10.201.20.97  |
| all    | 10.201.20.97  | 1409640060 |      3 | 10.201.20.97  |
| all    | 10.201.20.97  | 1409640000 |      4 | 10.201.20.97  |
| all    | 10.201.20.97  | 1409639940 |      5 | 10.201.20.97  |
| all    | 10.201.20.97  | 1409639880 |      6 | 10.201.20.97  |
| all    | 10.201.20.98  | 1409640180 |      1 | 10.201.20.98  |
| all    | 10.201.20.98  | 1409640120 |      2 | 10.201.20.98  |
| all    | 10.201.20.98  | 1409640060 |      3 | 10.201.20.98  |
| all    | 10.201.20.98  | 1409640000 |      4 | 10.201.20.98  |
| all    | 10.201.20.98  | 1409639940 |      5 | 10.201.20.98  |
| all    | 10.201.20.98  | 1409639880 |      6 | 10.201.20.98  |
+--------+---------------+------------+--------+---------------+
好了,再外面加一层inner join 再对 rownumber 做限制 就可以拿到目标数据了。

tudou@b2c.xiaomi.com

set @row=0;set @mid=&#39;&#39;;select a.*,b.rownum from total_freq_ctrl a inner join (SELECT module, machine, time, case when @mid = machine then @row:=@row+1 else @row:=1 end rownum, @mid:=machine mid FROM total_freq_ctrl order by module,machine,time desc) b on b.module=a.module and b.machine=a.machine and b.time=a.time where b.rownum<5;
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

+------------+---------------+--------+------------+-----------+--------+
| time       | machine       | module | total_flow | deny_flow | rownum |
+------------+---------------+--------+------------+-----------+--------+
| 1409640360 | 10.201.20.181 | all    |      53937 |      6058 |      1 |
| 1409640300 | 10.201.20.181 | all    |      52588 |      5701 |      2 |
| 1409640240 | 10.201.20.181 | all    |      54254 |      5608 |      3 |
| 1409640180 | 10.201.20.181 | all    |      54684 |      5811 |      4 |
| 1409640360 | 10.201.20.97  | all    |      50679 |      5307 |      1 |
| 1409640300 | 10.201.20.97  | all    |      50472 |      5239 |      2 |
| 1409640240 | 10.201.20.97  | all    |      51586 |      5509 |      3 |
| 1409640180 | 10.201.20.97  | all    |      50794 |      5378 |      4 |
| 1409640360 | 10.201.20.98  | all    |      84747 |      5652 |      1 |
| 1409640300 | 10.201.20.98  | all    |      84506 |      5696 |      2 |
| 1409640240 | 10.201.20.98  | all    |      84982 |      5513 |      3 |
| 1409640180 | 10.201.20.98  | all    |      83997 |      5623 |      4 |
+------------+---------------+--------+------------+-----------+--------+

推荐阅读
  • 【漫画解析】数据已删,存储空间为何未减?揭秘背后真相
    在数据迁移过程中,即使删除了原有数据,存储空间却未必会相应减少。本文通过漫画形式解析了这一现象背后的真相。具体来说,使用 `mysqldump` 命令进行数据导出时,该工具作为 MySQL 的逻辑备份工具,通过连接数据库并查询所需数据,将其转换为 SQL 语句。然而,这种操作并不会立即释放存储空间,因为数据库系统可能保留了已删除数据的碎片信息。文章进一步探讨了如何优化存储管理,以确保数据删除后能够有效回收存储空间。 ... [详细]
  • 本文介绍了MySQL中一些基本但重要的数学函数,包括角度与弧度之间的转换函数RADIANS(X)和DEGREES(X),以及正弦函数。RADIANS(X)用于将角度值转换为弧度值,而DEGREES(X)则将弧度值转换为角度值。这些函数在处理涉及角度和弧度的计算时非常有用,能够简化复杂的数学运算。此外,正弦函数在三角学和工程计算中也具有广泛的应用,能够帮助用户更高效地进行数据处理和分析。 ... [详细]
  • 如何在Android设备上通过应用程序创建浏览器书签 ... [详细]
  • 本文深入探讨了 DB2 SQL 中多列更新语句的应用与技巧,通过具体示例详细介绍了多列更新的语法和实际操作方法。例如,使用以下语法可以同时更新多个字段:```sqlUPDATE T_TableSET (字段A, 字段B) = (value_a, value_b);```文章还进一步分析了多列更新在性能优化和数据一致性方面的优势,并提供了实用的案例和最佳实践。 ... [详细]
  • 本文深入探讨了 MySQL 中 `ANALYZE TABLE` 和 `SHOW CREATE TABLE` 的语法规则及其应用。`ANALYZE TABLE` 语句用于分析并存储表的关键字分布情况,以优化查询性能。该操作在执行过程中会获取表的读锁,确保数据的一致性。而 `SHOW CREATE TABLE` 则用于显示创建表时的详细语句,包括表结构、索引和存储引擎等信息,有助于数据库管理和维护。通过这些命令,DBA 可以更好地理解和优化数据库性能。 ... [详细]
  • 在数据库设计中,谨慎使用外键至关重要。本文探讨了九个关键原因,包括数据完整性的维护、性能优化、系统复杂性的管理、数据迁移的灵活性以及对外部系统的依赖性控制。通过深入分析这些因素,可以帮助开发人员和架构师做出更明智的设计决策,确保数据库系统的高效与稳定。 ... [详细]
  • InnoDB当前仅支持一次创建一个FULLTEXT索引 ... [详细]
  • MySQL 数据备份与恢复的常见方法及其实践经验总结。物理备份涉及直接复制数据库文件,适用于大规模数据库环境,但无法在异构系统(如 Windows)中恢复。逻辑备份则侧重于导出建表语句和数据插入语句,便于跨平台迁移和部分数据恢复。此外,本文还探讨了增量备份、全量备份以及使用工具如 mysqldump 和 Percona XtraBackup 的具体应用场景和优缺点。 ... [详细]
  • 揭秘腾讯云CynosDB计算层设计优化背后的不为人知的故事与技术细节
    揭秘腾讯云CynosDB计算层设计优化背后的不为人知的故事与技术细节 ... [详细]
  • MySQL 数据变更后如何实现实时同步至 Elasticsearch
    在 MySQL 数据变更后,如何实现与 Elasticsearch 的实时同步是一个常见的需求。本文介绍了通过配置 MySQL 的 Binlog 功能,结合中间件如 Canal 或 Debezium,将数据变更事件实时捕获并同步到 Elasticsearch 中的方法。此外,还探讨了如何处理数据删除操作,确保 Elasticsearch 中的数据与 MySQL 保持一致。文章还简要对比了 VSCode 和 Dev 两种开发环境的优缺点,为开发者提供参考。 ... [详细]
  • 掌握PHP编程必备知识与技巧——全面教程在当今的PHP开发中,了解并运用最新的技术和最佳实践至关重要。本教程将详细介绍PHP编程的核心知识与实用技巧。首先,确保你正在使用PHP 5.3或更高版本,最好是最新版本,以充分利用其性能优化和新特性。此外,我们还将探讨代码结构、安全性和性能优化等方面的内容,帮助你成为一名更高效的PHP开发者。 ... [详细]
  • 在数据表中,我需要触发一个操作来刷新特定列的数据。例如,对于以下表格:| ID | Name | IsDeleted ||----|-------|-----------|| 1 | test | True || 2 | test2 | False |我希望在点击“更新”按钮时,能够仅刷新选定行的“IsDeleted”列。这将有助于确保数据的实时性和准确性。 ... [详细]
  • 在第二课中,我们将深入探讨Scala的面向对象编程核心概念及其在Spark源码中的应用。首先,通过详细的实战案例,全面解析Scala中的类和对象。作为一门纯面向对象的语言,Scala的类设计和对象使用是理解其面向对象特性的关键。此外,我们还将介绍如何通过阅读Spark源码来进一步巩固对这些概念的理解。这不仅有助于提升编程技能,还能为后续的高级应用开发打下坚实的基础。 ... [详细]
  • 如何使用R语言高效连接并操作MySQL数据库
    如何使用R语言高效连接并操作MySQL数据库 ... [详细]
  • 本文详细探讨了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社区 版权所有