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

如何避免获取多ID最新记录时的SQL JOIN操作?

如何移除SQL查询中的JOIN操作以获取指定ID的最新记录?

你可以用窗口函数替代JOIN来实现需求,无需关联原表即可获取每个ID的最新记录。以下是具体实现方案:

当前使用的查询语句

SELECT t.*
FROM   (SELECT id,
               max(date) AS latest_date
        FROM   table_name
        WHERE  id IN ( 1, 2, 3, 4 )
        GROUP  BY id) AS latest_records
       JOIN table_name t
         ON t.id = latest_records.id
            AND t.date = latest_records.latest_date 

示例表结构及数据

id, date, column
1, 24-2-2, data
1, 24-2-1, data1
2, 24-2-2, data
2, 24-2-1, data1

期望返回结果

id, date, column
1, 24-2-2, data
2, 24-2-2, data

无JOIN的实现方案

方法1:使用ROW_NUMBER()(单条最新记录)

如果每个ID只需要保留一条最新记录(即使存在多条同日期的最新记录,随机取其一),可以用ROW_NUMBER()窗口函数:

SELECT id, date, column
FROM (
    SELECT 
        id, 
        date, 
        column,
        -- 按ID分组,每组内按日期倒序排序,标记行号
        ROW_NUMBER() OVER (PARTITION BY id ORDER BY date DESC) AS row_num
    FROM table_name
    WHERE id IN (1, 2, 3, 4)
) AS ranked_records
WHERE row_num = 1;

方法2:使用RANK()(保留所有同日期的最新记录)

如果同一个ID存在多条日期相同的最新记录,需要全部保留,可以用RANK()替代ROW_NUMBER():

SELECT id, date, column
FROM (
    SELECT 
        id, 
        date, 
        column,
        -- 同日期的记录会获得相同的排名
        RANK() OVER (PARTITION BY id ORDER BY date DESC) AS rank_num
    FROM table_name
    WHERE id IN (1, 2, 3, 4)
) AS ranked_records
WHERE rank_num = 1;

说明

  • 窗口函数是SQL标准语法,支持MySQL 8.0+、PostgreSQL、SQL Server、Oracle等主流数据库。
  • 若表上存在(id, date)的复合索引,该查询的性能会更优,数据库可以直接按索引顺序读取数据,避免额外排序。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:20:02