千家信息网

MySQL中如何使用GROUP BY分组取字段最大值

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,小编给大家分享一下MySQL中如何使用GROUP BY分组取字段最大值,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!假设有
千家信息网最后更新 2026年11月01日MySQL中如何使用GROUP BY分组取字段最大值

小编给大家分享一下MySQL中如何使用GROUP BY分组取字段最大值,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!


假设有一个业务场景,需要查询用户登录记录信息,其中表结构如下:

  1. CREATE TABLE `tb` (

  2. `id` int(11) NOT NULL AUTO_INCREMENT,

  3. `uid` int(11) NOT NULL,

  4. `ip` varchar(16) NOT NULL,

  5. `login_time` datetime,

  6. PRIMARY KEY (`id`),

  7. KEY (`uid`)

  8. );


再来点测试数据:

  1. INSERT INTO tb SELECT null, 1001, '192.168.1.1', '2016-01-01 16:30:47';

  2. INSERT INTO tb SELECT null, 1003, '192.168.1.153', '2016-01-01 19:30:51';

  3. INSERT INTO tb SELECT null, 1001, '192.168.1.61', '2016-01-01 16:50:41';

  4. INSERT INTO tb SELECT null, 1002, '192.168.1.31', '2016-01-01 18:30:21';

  5. INSERT INTO tb SELECT null, 1002, '192.168.1.66', '2016-01-01 19:12:32';

  6. INSERT INTO tb SELECT null, 1001, '192.168.1.81', '2016-01-01 19:53:09';

  7. INSERT INTO tb SELECT null, 1001, '192.168.1.231', '2016-01-01 19:55:34';


表数据情况:

  1. +----+------+---------------+---------------------+

  2. | id | uid | ip | login_time |

  3. +----+------+---------------+---------------------+

  4. | 1 | 1001 | 192.168.1.1 | 2016-01-01 16:30:47 |

  5. | 2 | 1003 | 192.168.1.153 | 2016-01-01 19:30:51 |

  6. | 3 | 1001 | 192.168.1.61 | 2016-01-01 16:50:41 |

  7. | 4 | 1002 | 192.168.1.31 | 2016-01-01 18:30:21 |

  8. | 5 | 1002 | 192.168.1.66 | 2016-01-01 19:12:32 |

  9. | 6 | 1001 | 192.168.1.81 | 2016-01-01 19:53:09 |

  10. | 7 | 1001 | 192.168.1.231 | 2016-01-01 19:55:34 |

  11. +----+------+---------------+---------------------+



如果只需要针对用户查出其最后登录的时间,可以简单写出:

  1. SELECT uid, max(login_time)

  2. FROM tb

  3. GROUP BY uid;


  4. +------+---------------------+

  5. | uid | max(login_time) |

  6. +------+---------------------+

  7. | 1001 | 2016-01-01 19:55:34 |

  8. | 1002 | 2016-01-01 19:12:32 |

  9. | 1003 | 2016-01-01 19:30:51 |

  10. +------+---------------------+


若还需要查询用户最后登录时的其他信息,就不能用这种sql写了:

  1. -- 错误写法

  2. SELECT uid, ip, max(login_time)

  3. FROM tb

  4. GROUP BY uid;

  5. -- 错误写法

这样的语句是非SQL标准的,虽然能够在MySQL数据库中执行成功,但返回的却是未知的
(如果sql_mode开启了only_full_group_by,则不会执行成功。)
可能ip字段会取uid分组前的第一个row的值,显然不是所需信息


写法①
那么写一个子查询吧:

  1. SELECT a.uid, a.ip, a.login_time

  2. FROM tb a

  3. WHERE a.login_time in (

  4. SELECT max(login_time)

  5. FROM tb

  6. GROUP BY uid);


写法②
再或者换一个写法:

  1. SELECT a.uid, a.ip, a.login_time

  2. FROM tb a

  3. WHERE a.login_time = (

  4. SELECT max(login_time)

  5. FROM tb

  6. WHERE a.uid = uid);



顺便测了一下
在5.6以前的版本中,写法②这条sql在大数据量的情况下,执行计划不理想,目测性能不佳。
在5.6及以后的版本中,写法②这条sql会快很多,执行计划也有了改变


5.5.50:

  1. +----+--------------------+-------+------+---------------+------+---------+------+------+-------------+

  2. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

  3. +----+--------------------+-------+------+---------------+------+---------+------+------+-------------+

  4. | 1 | PRIMARY | a | ALL | NULL | NULL | NULL | NULL | 7 | Using where |

  5. | 2 | DEPENDENT SUBQUERY | tb | ALL | uid | NULL | NULL | NULL | 7 | Using where |

  6. +----+--------------------+-------+------+---------------+------+---------+------+------+-------------+



5.6.30:

  1. +----+--------------------+-------+------+---------------+------+---------+------------+------+-------------+

  2. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

  3. +----+--------------------+-------+------+---------------+------+---------+------------+------+-------------+

  4. | 1 | PRIMARY | a | ALL | NULL | NULL | NULL | NULL | 7 | Using where |

  5. | 2 | DEPENDENT SUBQUERY | tb | ref | uid | uid | 4 | test.a.uid | 1 | NULL |

  6. +----+--------------------+-------+------+---------------+------+---------+------------+------+-------------+



写法③
索性直接改成join性能会更加好:

  1. SELECT a.uid, a.ip, a.login_time

  2. FROM (SELECT uid, max(login_time) login_time

  3. FROM tb

  4. GROUP BY uid

  5. ) b JOIN tb a ON a.uid = b.uid AND a.login_time = b.login_time;


当然,结果都相同:

  1. +------+---------------+---------------------+

  2. | uid | ip | login_time |

  3. +------+---------------+---------------------+

  4. | 1003 | 192.168.1.153 | 2016-01-01 19:30:51 |

  5. | 1002 | 192.168.1.66 | 2016-01-01 19:12:32 |

  6. | 1001 | 192.168.1.231 | 2016-01-01 19:55:34 |

  7. +------+---------------+---------------------+


当然……如果要分组取最小值直接改对应函数和符号就行了。

以上是"MySQL中如何使用GROUP BY分组取字段最大值"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

写法 分组 数据 字段 信息 用户 篇文章 查询 登录 最大 最大值 成功 内容 性能 情况 版本 错误 最小 相同 不怎么 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 湖南永感互联网科技有限公司 科技与互联网 腾讯科技 互联网女皇 互联网科技上市公司 友谊互联网络科技 互联网科技的未来发展 国外互联网科技网站 人人互联网科技是培训 广州慧亚互联网科技怎么样 中国互联网有什么科技含量 科技与互联网哪个更好 花神(南京)互联网科技有限公司 呼和浩特新华互联网科技学院 深圳市罗太互联网科技有限公司 威龙国际互联网科技公司 无锡工业互联网科技有限公司 萌小萌互联网科技河南有限公司 福仕德教育科技互联网 马化腾互联网科技教学 网互联网络科技 上海互联网科技有限公司 齐家互联网科技 天津摩尔互联网科技 宁波青枫互联网科技有限公司 中国的互联网科技企业的崛起 互联网还是高科技吗 崇明区互联网教育科技诚信经营 新兴科技互联网创新大赛颁奖典礼 广州市恰铎互联网科技有限公司 云南互联网科技学费
0