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

PostgreSQL分组时如何获取指定列的最新数据?

PostgreSQL + Sequelize 分组后取最新字段值的最优方案

核心方案1:用PostgreSQL原生DISTINCT ON语法

这是处理「分组后取每组某排序规则下第一条数据」最简洁高效的方式,比子查询更直观,PostgreSQL对该语法有专门优化。

原生SQL示例

假设你的表名为locations,直接写SQL实现需求:

SELECT DISTINCT ON (address)
  address,
  distance,
  created_at
FROM locations
ORDER BY address, created_at DESC;

这段逻辑会先按address分组,每组内按created_at倒序排列,自动取每组第一条数据,正好匹配你要的「每个address对应最新created_at的distance值」需求。

Sequelize中实现

通过sequelize.literal()嵌入原生语法:

const result = await Location.findAll({
  attributes: [
    [sequelize.literal('DISTINCT ON (address) address'), 'address'],
    'distance',
    'created_at'
  ],
  order: [['address', 'ASC'], ['created_at', 'DESC']],
  raw: true // 可选,返回原始数据对象
});

核心方案2:窗口函数(兼容聚合场景)

如果需要同时搭配SUM这类聚合函数,用ROW_NUMBER()窗口函数更灵活,避免嵌套子查询的繁琐:

原生SQL示例

WITH ranked_data AS (
  SELECT
    address,
    distance,
    created_at,
    SUM(your_column) OVER (PARTITION BY address) AS total_sum,
    ROW_NUMBER() OVER (PARTITION BY address ORDER BY created_at DESC) AS rn
  FROM locations
)
SELECT address, distance, created_at, total_sum
FROM ranked_data
WHERE rn = 1;

Sequelize中实现

直接执行原生查询:

const result = await sequelize.query(`
  WITH ranked_data AS (
    SELECT
      address,
      distance,
      created_at,
      SUM(your_column) OVER (PARTITION BY address) AS total_sum,
      ROW_NUMBER() OVER (PARTITION BY address ORDER BY created_at DESC) AS rn
    FROM locations
  )
  SELECT address, distance, created_at, total_sum
  FROM ranked_data
  WHERE rn = 1;
`, { type: sequelize.QueryTypes.SELECT });

方案对比

  • DISTINCT ON:语法极简,仅需取每组最新值时优先用,性能最优
  • 窗口函数:支持同时处理聚合计算和取最新值,场景适配性更强

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 11:27:28