You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL查询:按device分组获取各分组最新时间戳的多列数据

需求与问题

需要查询数据表中的多列数据,其中device列仅包含"top"和"bot"两个唯一值,每行数据带有datetime时间戳,目标是获取每个device对应的最新datetime时间戳的完整记录。

数据表结构与数据

uid | datetime           | device | temp | hum
================================================
1   |2022-08-30 17:34:34 |top     |11.5  |88.90
2   |2022-08-30 17:34:22 |bot     |13.2  |88.90
3   |2020-10-06 13:48:33 |top     |24.3  |75.00
4   |2020-10-06 14:35:37 |bot     |21.7  |75.00

期望查询结果

datetime            | device | temp | hum
===========================================
2022-08-30 17:34:34 |top     |11.5  |88.90
2022-08-30 17:34:22 |bot     |13.2  |88.90

当前问题

执行现有SQL语句时,返回的是每个device的最早记录而非最新:

返回的错误结果

datetime            | device | temp | hum
===========================================
2020-10-06 13:48:33 |top     |24.3  |75.00
2020-10-06 14:35:37 |bot     |21.7  |75.00

当前使用的SQL语句

SELECT datetime, device, temp, hum 
FROM <table_name> 
WHERE uid=123456789 
GROUP BY device 
ORDER BY datetime DESC 
LIMIT 2

错误原因:GROUP BY device会默认取每组的第一条记录(不同数据库行为有差异,但均不会自动选取最新数据),后续的ORDER BY仅对分组后的结果排序,无法改变分组时选取的原始记录。

正确解决方案

方法1:使用窗口函数(推荐,适用于MySQL 8.0+、PostgreSQL、SQL Server等支持窗口函数的数据库)

利用ROW_NUMBER()窗口函数按device分组,每组内按datetime降序排序,取排序后行号为1的记录:

SELECT datetime, device, temp, hum
FROM (
    SELECT 
        datetime, device, temp, hum,
        ROW_NUMBER() OVER (PARTITION BY device ORDER BY datetime DESC) AS rn
    FROM <table_name>
    WHERE uid=123456789
) t
WHERE rn = 1;

方法2:子查询关联(兼容旧版MySQL等不支持窗口函数的数据库)

先通过子查询找出每个device对应的最大datetime,再关联原表获取完整记录:

SELECT t1.datetime, t1.device, t1.temp, t1.hum
FROM <table_name> t1
JOIN (
    SELECT device, MAX(datetime) AS max_dt
    FROM <table_name>
    WHERE uid=123456789
    GROUP BY device
) t2 ON t1.device = t2.device AND t1.datetime = t2.max_dt
WHERE t1.uid=123456789;

方法3:MAX()结合GROUP_CONCAT(仅MySQL适用,需注意字段类型兼容性)

通过GROUP_CONCAT按datetime降序拼接字段,再提取第一个值:

SELECT 
    SUBSTRING_INDEX(GROUP_CONCAT(datetime ORDER BY datetime DESC), ',', 1) AS datetime,
    device,
    SUBSTRING_INDEX(GROUP_CONCAT(temp ORDER BY datetime DESC), ',', 1) AS temp,
    SUBSTRING_INDEX(GROUP_CONCAT(hum ORDER BY datetime DESC), ',', 1) AS hum
FROM <table_name>
WHERE uid=123456789
GROUP BY device;

内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 20:39:27