如何用单个SELECT查询获取每个(name,address)组的最新last_read值?
获取每组(name,address)最新last_read值的单SELECT方案
嘿,这个需求太常见了!不用写复杂的逻辑,单条SELECT就能搞定,给你两种最实用的方案,看你的数据库版本选就行:
方案1:窗口函数(推荐,适合现代数据库)
如果你的数据库支持窗口函数(比如MySQL 8.0+、PostgreSQL、SQL Server、Oracle等),用ROW_NUMBER()是最简洁高效的写法:
SELECT name, address, time, last_read FROM ( SELECT name, address, time, last_read, ROW_NUMBER() OVER (PARTITION BY name, address ORDER BY time DESC) AS rn FROM your_table_name ) AS ranked WHERE rn = 1;
原理说明:
PARTITION BY name, address:把数据按name和address的组合分成不同的组ORDER BY time DESC:每组内按时间倒序排列,最新的记录排在最前面ROW_NUMBER()给每组的记录编序号,最新的那条序号是1,最后外层查询筛选出rn=1的记录就行
小提示:如果同一组里有多条记录的time完全相同,ROW_NUMBER()会随机选一条;如果想返回所有同时间的最新记录,把ROW_NUMBER()换成RANK()就行。
方案2:子查询关联(兼容老版本数据库)
如果你的数据库不支持窗口函数(比如MySQL 5.x),可以用子查询先获取每组的最大时间,再和原表关联:
SELECT t1.name, t1.address, t1.time, t1.last_read FROM your_table_name t1 INNER JOIN ( SELECT name, address, MAX(time) AS max_time FROM your_table_name GROUP BY name, address ) AS t2 ON t1.name = t2.name AND t1.address = t2.address AND t1.time = t2.max_time;
原理说明:
- 子查询
t2先算出每个(name,address)组合对应的最新时间max_time - 然后用
INNER JOIN把原表t1和t2关联,匹配name、address和time,就能拿到对应时间的last_read值
注意:如果同一组同一时间有多条记录,这个查询会返回所有符合条件的记录,和方案1里用RANK()的效果一致。
内容的提问来源于stack exchange,提问作者taytibob77
相关产品推荐
相关产品推荐

