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

MySQL 1:N关联表中查询各对象对应最早照片URI:能否无需子查询实现单SQL查询?

如何用无嵌套相关子查询的MySQL语句获取每个object对应的最早上传照片的URI?

问题描述

我在MySQL中有object和photo两张表,二者为一对多(1:N)关联关系,即一个object可对应多个photo。photo表包含id、object_id、uploaded_at、uri字段。我需要编写一条SELECT语句,查询每个object_id对应的最早(上传时间最早)照片的uri。目前已通过以下查询语句实现需求:

select object_id, uri from photo ph where uploaded_at = (SELECT min(uploaded_at) from photo inph where inph.object_id = ph.object_id) group by object_id, uri;

请问是否可以通过一条不包含子查询的SQL语句实现该需求?

解决方案

当然可以!有两种常用的方法可以实现这个需求,不需要在WHERE子句里写依赖外层表字段的相关子查询,下面分别说明:

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

如果你使用的是MySQL 8.0或更高版本,窗口函数ROW_NUMBER()是最简洁清晰的方案。它可以按object_id分组,给每组内的记录按uploaded_at升序排序,然后我们只取排序后的第一条记录(也就是最早的照片):

SELECT object_id, uri
FROM (
    SELECT 
        object_id, 
        uri,
        ROW_NUMBER() OVER (PARTITION BY object_id ORDER BY uploaded_at ASC) AS rn
    FROM photo
) AS ranked_photos
WHERE rn = 1;

这里的子查询是独立计算排序结果,不属于依赖外层表的相关子查询,逻辑直观,后续维护也更方便。如果存在多个照片同时为最早上传的情况,可以在ORDER BY后追加id ASC,确保只返回id最小的那条记录:

ROW_NUMBER() OVER (PARTITION BY object_id ORDER BY uploaded_at ASC, id ASC) AS rn

方法二:使用GROUP BY + JOIN(兼容低版本MySQL)

如果你的MySQL版本低于8.0,不支持窗口函数,可以先通过GROUP BY计算每个object_id对应的最早上传时间,再通过JOIN关联原表获取对应的uri:

SELECT ph.object_id, ph.uri
FROM photo ph
JOIN (
    SELECT object_id, MIN(uploaded_at) AS earliest_upload_time
    FROM photo
    GROUP BY object_id
) AS min_upload_dates 
    ON ph.object_id = min_upload_dates.object_id 
    AND ph.uploaded_at = min_upload_dates.earliest_upload_time;

这个方法同样避免了WHERE子句中的相关子查询,通过预先计算每个object的最早时间,再做关联匹配,兼容性更好。同样,如果有多个照片时间相同,会返回所有符合条件的记录,可根据业务需求调整。

内容的提问来源于stack exchange,提问作者peter.cambal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 17:52:43