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

MySQL查询:按tc.sno去重并获取最新日期的记录

解决MySQL查询每个唯一tc.sno最新日期行的问题

我明白你的需求了——你需要从当前的关联查询结果中,针对每个唯一的tc.sno,只保留对应st.date最新的那一行数据,对吧?下面给你两种常用的解决方案,适配不同版本的MySQL:

方法一:使用窗口函数(MySQL 8.0+ 推荐)

窗口函数是处理这类“分组取Top1”场景最简洁高效的方式,我们可以用ROW_NUMBER()给每个tc.sno分组内的行按日期倒序编号,然后只取编号为1的行:

WITH ranked_data AS (
    SELECT 
        st.seno, 
        tc.pl, 
        tc.sno, 
        st.val1, 
        st.val2, 
        st.date,
        -- 按tc.sno分组,每行按st.date降序生成序号
        ROW_NUMBER() OVER (PARTITION BY tc.sno ORDER BY st.date DESC) AS rn
    FROM tc 
    LEFT JOIN st ON tc.seno = st.seno AND tc.pl = st.pl AND st.seno = 1304239136 
    WHERE tc.pl = 1
)
SELECT seno, pl, sno, val1, val2, date
FROM ranked_data
WHERE rn = 1; -- 只保留每个sno的最新行

逻辑说明:

  • PARTITION BY tc.sno:把数据按tc.sno分成不同的组
  • ORDER BY st.date DESC:每个组内按日期从新到旧排序
  • ROW_NUMBER():给每个组内的行依次编号,最新的那行编号为1
  • 外层查询筛选rn=1,就能得到每个tc.sno的最新数据行

方法二:兼容MySQL 5.x版本(无窗口函数)

如果你的MySQL版本低于8.0,不支持窗口函数,可以用子查询先找到每个tc.sno对应的最大日期,再关联原查询获取完整数据:

SELECT 
    st.seno, 
    tc.pl, 
    tc.sno, 
    st.val1, 
    st.val2, 
    st.date
FROM tc 
LEFT JOIN st ON tc.seno = st.seno AND tc.pl = st.pl AND st.seno = 1304239136 
WHERE tc.pl = 1
AND (tc.sno, st.date) IN (
    -- 子查询:找到每个tc.sno对应的最大st.date
    SELECT tc_inner.sno, MAX(st_inner.date)
    FROM tc tc_inner
    LEFT JOIN st st_inner ON tc_inner.seno = st_inner.seno AND tc_inner.pl = st_inner.pl AND st_inner.seno = 1304239136
    WHERE tc_inner.pl = 1
    GROUP BY tc_inner.sno
);

额外注意:

  • 如果某个tc.sno对应的st.date为NULL(也就是左连接后没有匹配到st表的数据),MAX(st.date)会返回NULL,这条数据也会被保留,和你原语句的左连接逻辑一致
  • 如果同一个tc.sno有多个行的st.date完全相同,方法一的ROW_NUMBER()会随机选一行;要是想保留所有同日期的行,可以把ROW_NUMBER()换成RANK()

这样就能精准得到每个唯一tc.sno的最新日期行啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:45:35