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

PostgreSQL中查询仅在table_1且按最大采集日期过滤的名称

解决方案:PostgreSQL 找出table_1独有的名称并保留最大日期记录

一、使用HAVING的正确写法

HAVING仅用于过滤分组后的聚合结果,必须先对name分组,结合聚合函数筛选。

场景1:仅获取名称和对应最大日期

SELECT 
    t1.name,
    MAX(t1.date_collected) AS latest_collected_date
FROM table_1 t1
-- 过滤出仅存在于table_1的名称
WHERE NOT EXISTS (
    SELECT 1 
    FROM table_2 t2 
    WHERE t2.name = t1.name
)
GROUP BY t1.name

场景2:获取最大日期的完整记录

如果需要这条记录的所有字段,单纯GROUP BY+HAVING无法直接实现(GROUP BY需要包含所有非聚合字段),可以结合子查询实现类似HAVING的筛选逻辑:

SELECT t1.*
FROM table_1 t1
WHERE NOT EXISTS (SELECT 1 FROM table_2 t2 WHERE t2.name = t1.name)
AND t1.date_collected = (
    SELECT MAX(date_collected) 
    FROM table_1 
    WHERE name = t1.name
)

二、无需HAVING的更灵活方法

方法1:窗口函数(推荐)

用ROW_NUMBER()给每个名称的记录按日期降序编号,取编号为1的记录即为最大日期的那条:

SELECT 
    name,
    date_collected,
    -- 此处添加其他需要的字段
FROM (
    SELECT 
        t1.*,
        ROW_NUMBER() OVER (
            PARTITION BY t1.name 
            ORDER BY t1.date_collected DESC
        ) AS row_num
    FROM table_1 t1
    WHERE NOT EXISTS (
        SELECT 1 
        FROM table_2 t2 
        WHERE t2.name = t1.name
    )
) ranked_data
WHERE row_num = 1

如果同一名称存在多条相同的最大日期记录,改用RANK()可以保留所有并列的记录。

方法2:子查询关联

先查询每个名称的最大日期,再关联回原表获取完整记录:

SELECT t1.*
FROM table_1 t1
INNER JOIN (
    SELECT 
        name,
        MAX(date_collected) AS max_date
    FROM table_1
    GROUP BY name
) t1_latest 
    ON t1.name = t1_latest.name 
    AND t1.date_collected = t1_latest.max_date
WHERE NOT EXISTS (
    SELECT 1 
    FROM table_2 t2 
    WHERE t2.name = t1.name
)

常见错误解析

  • WHERE子句不能用聚合函数:WHERE是分组前过滤单行数据,聚合函数(如MAX())是对分组后的集合计算,因此不能直接在WHERE中使用WHERE date_collected = MAX(date_collected)。
  • HAVING参数类型错误:HAVING只能引用分组字段或聚合函数,若引用未分组的普通字段会触发类型错误,此时应改用子查询或窗口函数实现筛选。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 18:32:37