mysql 分组 排序 取时间最大的一条记录

MySQL分组排序示例
本文提供了一个MySQL查询示例,展示了如何通过分组和排序获取每个分组中时间最新的记录。具体操作包括使用子查询确定每个aid的最大day值,并以此筛选出相应的记录。
mysql 分组 group by, 排序 取每条记录中,时间最大的一条记录


SELECT A.* FROM test A,
(SELECT aid, MAX(day) max_day FROM test GROUP BY aid) B
WHERE A.aid = B.aid AND A.day = B.max_day
ORDER BY a.install DESC

以下是 test 表,测试sql


CREATE TABLE IF NOT EXISTS `test` (
`id` int(10) unsigned NOT NULL auto_increment,
`install` int(10) unsigned NOT NULL,
`day` int(10) unsigned NOT NULL,
`aid` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=12 ;


INSERT INTO `test` (`id`, `install`, `day`, `aid`) VALUES
(1, 1232, 20080808, 1),
(2, 2321, 20080809, 2),
(3, 1236, 20080810, 3),
(5, 4212, 20080809, 1),
(6, 2312, 20080810, 1),
(7, 1432, 20080811, 1),
(8, 2421, 20080808, 2),
(9, 4245, 20080811, 2),
(10, 5654, 20080810, 2),
(11, 412, 20080808, 3);
http://download.farsight.com.cn/download/pdf/Farsight090607-android.pdf
MySQL 中实现分组排序每组第一条数据,通常需要结合排序分组操作。由于 MySQL 早期版本不支持窗口函数,因此实现方式通常较为复杂。以下介绍几种实现方法: ### 方法一:使用子查询和 `JOIN` 通过子查询获每组排序后的第一条记录的唯一标识(如 `id`),然后使用 `JOIN` 查询获完整的记录。这种方法适用于数据量较小的情况。 ```sql SELECT t1.* FROM your_table t1 INNER JOIN ( SELECT MIN(id) AS min_id -- 假设 id 是唯一标识字段 FROM your_table GROUP BY group_column -- 按照指定的分组字段 ) t2 ON t1.id = t2.min_id; ``` 这种方法的核心是通过 `MIN(id)` 获每个分组中第一条记录的唯一标识,然后通过 `JOIN` 获完整的记录信息[^4]。 --- ### 方法二:使用窗口函数(适用于 MySQL 8.0 及以上版本) MySQL 8.0 引入了窗口函数,可以更高效地实现分组排序每组第一条记录。通过 `ROW_NUMBER()` 函数为每组数据分配一个行号,然后筛选出每组的行号为 1 的记录。 ```sql SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY group_column ORDER BY sort_column DESC) AS rn FROM your_table ) t WHERE rn = 1; ``` - `PARTITION BY group_column`:按照指定的列对结果集进行分区。 - `ORDER BY sort_column DESC`:在每个分区内按照排序字段进行降序排列。 - `ROW_NUMBER()`:为每行分配一个唯一的行号。 - 最外层查询筛选出行号为 1 的记录,即每组的第一条记录[^5]。 --- ### 方法三:使用 `GROUP BY` 和子查询结合排序 如果数据量较大,但无法使用窗口函数,可以通过排序和 `GROUP BY` 的结合实现分组一条记录。 ```sql SELECT t.stu_name, t.course_name, t.score FROM ( SELECT * FROM t_student_score ORDER BY score DESC ) t GROUP BY t.course_name; ``` 此方法通过先对数据进行排序,确保每组的第一条记录排序后的第一条,然后通过 `GROUP BY` 获每组的第一条记录[^2]。 --- ### 方法四:使用临时表和自连接 通过创建临时表存储排序后的数据,然后使用自连接获每组的第一条记录。 ```sql CREATE TEMPORARY TABLE temp_table AS SELECT *, @row_number := IF(@group = group_column, @row_number + 1, 1) AS rn, @group := group_column FROM your_table ORDER BY group_column, sort_column DESC; SELECT * FROM temp_table WHERE rn = 1; ``` - `@row_number` 和 `@group` 是用户变量,用于生成行号。 - 通过 `ORDER BY group_column, sort_column DESC` 确保每组数据按照指定字段排序。 - 最终查询筛选出行号为 1 的记录,即每组的第一条记录。 --- ### 方法比较 1. **方法一**:适用于数据量较小的情况,但效率较低。 2. **方法二**:推荐使用,尤其在 MySQL 8.0 及以上版本中,性能较高且代码简洁。 3. **方法三**:简单易懂,但依赖 `GROUP BY` 的行为,可能在某些版本中表现不一致。 4. **方法四**:灵活且性能较好,适合处理复杂排序需求。 根据实际需求和 MySQL 版本选择合适的方法实现分组排序每组第一条记录。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值