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

如何用单条PostgreSQL查询获取所有Foo及其最新关联Bar?

问题描述

现有foos表和bars表,一个Foo对应多个Bar,需通过单条PostgreSQL查询返回所有Foo及其对应的最新Bar。

表结构

foos表

idname
1Foo1
2Foo2

bars表

idfoo_idcreated_date
112022-12-02 13:00:00
212022-12-02 13:30:00
322022-12-02 14:00:00
422022-12-02 14:30:00

预期结果

idnamebar.idbar.foo_idbar.created_date
1Foo1212022-12-02 13:30:00
2Foo2422022-12-02 14:30:00

解决方案:窗口函数法(推荐)

利用PostgreSQL的ROW_NUMBER()窗口函数,按foo_id分组并按创建时间倒序排序,筛选出每组的第一条(最新)记录,再与foos表关联:

SELECT 
    f.id,
    f.name,
    b.id AS "bar.id",
    b.foo_id AS "bar.foo_id",
    b.created_date AS "bar.created_date"
FROM foos f
LEFT JOIN (
    SELECT 
        *,
        ROW_NUMBER() OVER (PARTITION BY foo_id ORDER BY created_date DESC) AS rn
    FROM bars
) b ON f.id = b.foo_id AND b.rn = 1;

说明

  • 子查询中,PARTITION BY foo_id将bars按所属Foo分组,ORDER BY created_date DESC让组内记录从新到旧排序,ROW_NUMBER()为每组记录分配序号,最新记录序号为1。
  • 外层通过LEFT JOIN关联,仅保留序号为1的记录,确保每个Foo对应最新的Bar;若只需返回有对应Bar的Foo,可替换为INNER JOIN。
  • 若存在多条Bar创建时间相同且均为最新的情况,ROW_NUMBER()会随机取一条,若需保留所有最新记录,可改用RANK()函数。

备选方案:关联子查询法

SELECT 
    f.id,
    f.name,
    b.id AS "bar.id",
    b.foo_id AS "bar.foo_id",
    b.created_date AS "bar.created_date"
FROM foos f
LEFT JOIN bars b ON f.id = b.foo_id
WHERE b.created_date = (
    SELECT MAX(created_date) FROM bars WHERE foo_id = f.id
);

说明

  • 此方法通过子查询获取每个Foo对应的最新created_date,再关联筛选出对应记录。
  • 缺点:若存在多条Bar创建时间相同且为最新,会返回多条记录;数据量大时性能不如窗口函数法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 17:11:18