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

如何获取仅含最新创建记录的1:n表关联查询结果?

解决按分组取最新记录并关联子表的问题

这个需求其实挺典型的——要先锁定每组(id_something+date_day)里created最新的那条主表记录,再把它和子表的所有关联数据拉出来。我给你两个通用的、非Oracle专属的方案,性能和可读性都不错:

方案一:用窗口函数(推荐,性能最优)

窗口函数是处理这类分组取TOP N场景的利器,逻辑清晰而且效率高。我们先给主表的每条记录按分组排序,标记出每组里最新的那条,再关联子表:

WITH ranked_one AS (
    SELECT 
        *,
        -- 按id_something+date_day分组,组内按created倒序排,最新的记录行号为1
        ROW_NUMBER() OVER (PARTITION BY id_something, date_day ORDER BY created DESC) AS rn
    FROM one
)
-- 只取每组行号为1的记录,再关联表二的所有对应数据
SELECT r.id, r.id_something, r.date_day, r.created, t.id_one, t.foo, t.bar
FROM ranked_one r
LEFT JOIN two t ON r.id = t.id_one
WHERE r.rn = 1;

如果你的业务允许同一组存在多条created完全相同的“并列最新”记录,可以把ROW_NUMBER()换成RANK(),这样会保留所有并列的记录。

方案二:子查询筛选最新记录(兼容老版本数据库)

如果你的数据库不支持CTE(比如MySQL 5.7及以前),可以用子查询先找出每组的最大created值,再反向匹配主表记录,最后关联子表:

SELECT o.id, o.id_something, o.date_day, o.created, t.id_one, t.foo, t.bar
FROM one o
LEFT JOIN two t ON o.id = t.id_one
WHERE (o.id_something, o.date_day, o.created) IN (
    -- 先算出每组的最新created时间
    SELECT id_something, date_day, MAX(created)
    FROM one
    GROUP BY id_something, date_day
);

这个方案要注意:如果同一组有多个记录的created等于最大值,会返回所有这些记录;如果业务上每组只会有一条最新记录,这个写法完全没问题。

为什么你之前的尝试没成功?

你提到用GROUP BY只能返回单行,是因为GROUP BY会把每组合并成一条记录,没法保留子表的多对一关联数据。我们的思路是先筛选出符合条件的主表记录,再关联子表,这样就能保留子表的所有对应键值对了。

另外,给主表的(id_something, date_day, created)字段建个联合索引,能让这两个方案的性能大幅提升,尤其是数据量大的时候。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:44:44