MySQL中group by max如何提取最大的一条记录

本文介绍了如何在MySQL中利用GROUP BY和MAX函数结合,从tab_game_version表中查询每个game_code对应的最高游戏版本及其详细信息。通过示例数据,展示了查询方法,帮助理解这一操作。
tab_game

mysql> select * from tab_game;
+----+-----------+-----------+-----------------+
| id | game_code | game_name | game_desc       |
+----+-----------+-----------+-----------------+
|  1 | 1001      | doudizhu  | doudizhuhaowan  |
|  2 | 1002      | majiang   | cuomajiangbucuo |
|  3 | 1003      | fahongbao | hongbaoxiangyao |
+----+-----------+-----------+-----------------+

tab_game_version

mysql> select * from tab_game_version;
+----+-----------+------------------+-----------+
| id | game_code | game_version_int | game_size |
+----+-----------+------------------+-----------+
|  1 | 1001      |               11 | 5MB       |
|  2 | 1001      |               12 | 6MB       |
|  3 | 1001      |               15 | 8MB       |
|  4 | 1002      |               10 | 1MB       |
|  5 | 1002      |               20 | 2MB       |
|  6 | 1003      |             1000 | 7MB       |
|  7 | 1003      |             2000 | 9MB       |
+----+-----------+------------------+-----------+

 有这样的两张表,要查出每个游戏的最大的game_version_int值的记录 

 最终想得到的结果是
game_code   game_name  game_version_int game_size
1001        斗地主         15               8MB
1002        搓麻将         20               2MB 
1003        发送包         2000             9MB


SQL 实现
第一种方式   不通用,只在MYSQL中可以用
mysql>  select game_code,max(game_version_int),game_size
    -> select * from tab_game_version t1 order by t1.gam
nt desc) t group by game_code ;
+-----------+-----------------------+-----------+
| game_code | max(game_version_int) | game_size |
+-----------+-----------------------+-----------+
| 1001      |                    15 | 8MB       |
| 1002      |                    20 | 2MB       |
| 1003      |                  2000 | 9MB       |
+-----------+-----------------------+-----------+
第二种方式,采用字符串拼接的方式,可以解决

mysql>  select * from tab_game_version where
    -> concat(game_code,game_version_int)
    -> in (select concat(game_code,max(game_version_int)) from tab_game_version
t1 group by t1.game_code )  ;
+----+-----------+------------------+-----------+
| id | game_code | game_version_int | game_size |
+----+-----------+------------------+-----------+
|  3 | 1001      |               15 | 8MB       |
|  5 | 1002      |               20 | 2MB       |
|  7 | 1003      |             2000 | 9MB       |
+----+-----------+------------------+-----------+

第三种方式,

mysql>  select a.game_code,b.game_size,a.game_version_int,c.game_name from (sele
ct game_code,max(game_version_int) game_version_int from tab_game_version group
by game_code) a
    -> left join tab_game_version b on a.game_code = b.game_code and a.game_vers
ion_int = b.game_version_int  left join tab_game c on b.game_code = c.game_code
;
+-----------+-----------+------------------+-----------+
| game_code | game_size | game_version_int | game_name |
+-----------+-----------+------------------+-----------+
| 1001      | 8MB       |               15 | doudizhu  |
| 1002      | 2MB       |               20 | majiang   |
| 1003      | 9MB       |             2000 | fahongbao |
+-----------+-----------+------------------+-----------+


### 如何在 MySQL 中使用 GROUP BY每组的最值记录MySQL 查询中,`GROUP BY` 是一种常用的聚合方式,用于按某一字段分组并返回汇总结果。然而,如果需要获每组内的某些特定条件下的记录(例如每组的最大值或最小值对应的整行数据),则需要结合子查询或其他技巧来完成。 #### 方法一:通过自连接实现 可以利用 `JOIN` 将原始表与其自身的子查询结果关联起来,从而提取出符合条件的每一行数据。以下是具体的 SQL 实现: ```sql SELECT t1.* FROM table_name AS t1 INNER JOIN ( SELECT ClsNo, MAX(Score) AS MaxScore FROM table_name GROUP BY ClsNo ) AS t2 ON t1.ClsNo = t2.ClsNo AND t1.Score = t2.MaxScore; ``` 上述代码的作用是从 `table_name` 表中按照班级号 (`ClsNo`) 分组,并找出每个班分数最高的学生信息[^1]。 --- #### 方法二:使用窗口函数 (适用于支持窗口函数的版本) 从 MySQL 8.0 开始引入了窗口函数功能,可以通过更简洁的方式解决此类问题。以下是一个例子: ```sql WITH RankedScores AS ( SELECT *, ROW_NUMBER() OVER(PARTITION BY ClsNo ORDER BY Score DESC) AS RowNum FROM table_name ) SELECT * FROM RankedScores WHERE RowNum = 1; ``` 这段代码先创建了一个临时视图 `RankedScores`,其中包含了每条记录在其所属分组中的排名情况;接着筛选出了排名第一的结果作为最终输出[^3]。 注意:此方法仅限于 MySQL 版本 >= 8.0 的环境中有效。 --- #### 性能优化建议 对于大数据量场景下的性能调优非常重要。以下几点可以帮助提高效率: - **合理设计索引**:确保参与排序的关键字段已建立适当类型的索引(如普通索引、复合索引)。这样能够减少全表扫描带来的开销[^5]。 - **避免不必要的计算**:尽量简化子查询逻辑,只保留必要的过滤条件。 - **评估执行计划**:借助 EXPLAIN 工具查看实际运行路径是否存在潜在瓶颈位置[^2]。 综上所述,无论是采用传统手段还是现代特性都可以很好地满足需求,但在实际应用过程中还需综合考虑业务特点与硬件资源状况做出最优决策。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值