pgsql 中,根据字段分组且每一组只获取一条记录

pgsql 中,表 t1 有多个字段 a1 a2 a3,相同a1 的值只查询一条数据

 

一、方法1 —使用 ROW_NUMBER() 窗口函数

SELECT *
FROM (
    SELECT *,
        ROW_NUMBER() OVER (PARTITION BY a1 ORDER BY a2) AS rn
    FROM t1
) subquery
WHERE rn = 1;
说明:
    • PARTITION BY a1:按照 a1 字段对数据进行分组。
    • ORDER BY a2:在每个分组内,按照 a2 字段进行排序。你可以根据实际需求调整排序字段。
    • rn = 1:筛选出每组排序后的第一条记录。

二、方法2 — 使用 DISTINCT ON(简洁高效)

SELECT DISTINCT ON (a1) *
FROM t1
ORDER BY a1, a2; -- 先按 a1 分组,再按 a2 排序取第一条
说明:
    • DISTINCT ON (a1):针对 a1 字段进行去重,仅保留每组的第一条记录。
    • ORDER BY a1, a2:排序顺序很关键,它决定了每组中哪条记录会被优先返回。

三、方法3 — 使用 GROUP BY 和聚合函数

若你只需要部分字段,可通过 GROUP BY 结合聚合函数来实现。

SELECT 
    a1,
    MAX(a2) AS a2, -- 选择每组中的最大值,可按需替换为其他聚合函数
    MAX(a3) AS a3
FROM t1
GROUP BY a1;
说明:
    • 该方法要求除 GROUP BY 字段外的其他字段都使用聚合函数。
    • 适用于只需获取聚合值,而非完整记录的场景。

四、使用 LATERAL 子查询

通过 LATERAL 子查询,为每个 a1 值动态关联匹配的记录。

SELECT t.*
FROM (SELECT DISTINCT a1 FROM t1) AS d
LATERAL (
    SELECT *
    FROM t1
    WHERE a1 = d.a1
    ORDER BY a2
    LIMIT 1
) t;
说明:
  • 先获取所有不同的 a1 值。
  • 针对每个 a1 值,执行子查询返回排序后的第一条记录。

五、选择建议

    • 优先考虑 DISTINCT ON:语法简洁,性能优良,适合获取完整记录。
    • 使用 ROW_NUMBER():当需要更复杂的筛选条件,比如获取每组的第二条记录时,可选用此方法。
    • 采用 GROUP BY:若只需部分字段的聚合值,可使用该方法。
    • 考虑 LATERAL:在需要关联其他表或进行复杂计算时,可选择此方法。
posted @ 2025-05-20 17:51  BillyYang  阅读(461)  评论(0)    收藏  举报