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

如何获取MySQL分组中timestamp类型列的最大值并按该值倒序排序

问题原因

你当前写法的核心问题是:MySQL非严格SQL模式下允许SELECT *和GROUP BY共用,但此时返回的非分组字段、非聚合字段会取分组内随机匹配的第一条记录,并不是你需要的最新时间对应的那条记录,所以你拿到的pm_entry_start不是分组最大值,才会出现显示时间和排序逻辑不符的问题。

解决方案

方案1:兼容所有MySQL版本(推荐,适配5.x及以上版本)

先通过子查询拿到每个分组的最大时间,再关联回原表获取对应最新消息的完整字段:

SELECT m.*
FROM market_messages m
INNER JOIN (
    SELECT 
        pm_item_id, 
        pm_item_client_id, 
        pm_item_sender_id, 
        MAX(pm_entry_start) AS max_entry_time
    FROM market_messages
    WHERE (pm_item_client = ? AND pm_item_client_id = ?) 
       OR (pm_item_sender = ? AND pm_item_sender_id = ?)
    GROUP BY pm_item_id, pm_item_client_id, pm_item_sender_id
) AS group_max 
ON m.pm_item_id = group_max.pm_item_id 
AND m.pm_item_client_id = group_max.pm_item_client_id 
AND m.pm_item_sender_id = group_max.pm_item_sender_id 
AND m.pm_entry_start = group_max.max_entry_time
ORDER BY group_max.max_entry_time DESC;

方案2:MySQL 8.0+ 版本可用(窗口函数写法更简洁)

通过ROW_NUMBER()窗口函数给每个分组内的消息按时间倒序编号,取编号为1的即为分组内最新消息:

SELECT * FROM (
    SELECT 
        *,
        ROW_NUMBER() OVER (
            PARTITION BY pm_item_id, pm_item_client_id, pm_item_sender_id 
            ORDER BY pm_entry_start DESC
        ) AS rn
    FROM market_messages
    WHERE (pm_item_client = ? AND pm_item_client_id = ?) 
       OR (pm_item_sender = ? AND pm_item_sender_id = ?)
) AS t
WHERE rn = 1
ORDER BY pm_entry_start DESC;

注意事项

你原写法中直接拼接$user_name、$user_id变量到SQL中存在SQL注入风险,建议使用PDO或mysqli的预处理语句,用上述语句中的?占位符传递变量,安全性更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 12:45:05