编写三表INNER JOIN查询:仅匹配C表最新记录满足条件的A表数据
解决方案
你可以通过先提取每个B表记录对应的C表最新数据,再做关联筛选的逻辑实现需求,以下是两种常用实现方案:
方案1:支持窗口函数的数据库(MySQL 8.0+/PostgreSQL/SQL Server等)
SELECT DISTINCT a.* FROM tableA a -- 关联满足slug条件的B表记录 INNER JOIN tableB b ON a.id = b.tableAId AND b.slug = 'foo' -- 关联每个B表对应的最新C表记录 INNER JOIN ( SELECT *, -- 按B表ID分组,按创建时间倒序排序,最新的记录序号为1,加id排序避免同时间多条数据的冲突 ROW_NUMBER() OVER (PARTITION BY tableBId ORDER BY createdAt DESC, id DESC) AS rn FROM tableC ) c_latest ON b.id = c_latest.tableBId AND c_latest.rn = 1 -- 仅保留最新C记录状态符合要求的结果 WHERE c_latest.status = 'approved';
逻辑说明
子查询先对C表按关联的B表ID分组,每组内按创建时间倒序排序,取每组第一条就是对应B表的最新C记录,后续仅校验该条记录的状态,完全符合你的筛选要求。你提供的示例中,B表ID=4对应的最新C记录状态为pending,会被WHERE条件过滤,最终返回空结果,符合预期。
方案2:兼容不支持窗口函数的低版本数据库(如MySQL 5.x)
SELECT DISTINCT a.* FROM tableA a INNER JOIN tableB b ON a.id = b.tableAId AND b.slug = 'foo' INNER JOIN ( -- 先取每个B表对应的C表最大创建时间 SELECT c1.* FROM tableC c1 INNER JOIN ( SELECT tableBId, MAX(createdAt) AS max_create_at FROM tableC GROUP BY tableBId ) c2 ON c1.tableBId = c2.tableBId AND c1.createdAt = c2.max_create_at ) c_latest ON b.id = c_latest.tableBId WHERE c_latest.status = 'approved';
逻辑说明
先通过分组聚合拿到每个B表关联的C表最新创建时间,再关联回C表拿到对应最新记录,后续筛选逻辑和方案1一致。
内容的提问来源于stack exchange,提问作者Bruno Ramos
相关产品推荐
相关产品推荐

