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

如何使用PostgreSQL的LAG()函数仅获取单条结果

解决方案与问题解答

LAG()函数是否适用?

是的,LAG()完全适用于这个场景。它的核心作用就是在按指定顺序排序的分区中,获取当前行的前一行数据,正好匹配你需要获取最新记录的前一日收盘价的需求。你之前的查询只是缺少了筛选最新记录的步骤,所以返回了所有行的变动数据。

最佳实现方式

这里提供几种高效的实现方式,其中窗口函数组合的写法最简洁通用:

方式1:结合ROW_NUMBER()筛选最新记录

通过ROW_NUMBER()给每条记录按时间倒序编号,最新的记录编号为1,最后筛选出这条记录即可:

SELECT stock_id, last_price, date, one_day_change
FROM (
    SELECT stock_id,
           close AS last_price,
           timestamp::DATE AS date,
           LAG(close) OVER (PARTITION BY stock_id ORDER BY timestamp DESC) AS one_day_change,
           ROW_NUMBER() OVER (PARTITION BY stock_id ORDER BY timestamp DESC) AS rn
    FROM historical_prices 
    WHERE stock_id = 2
) sub_query
WHERE rn = 1;

方式2:用CTE+最大值筛选

先通过CTE计算所有行的LAG值,再筛选出日期最新的那条记录:

WITH price_change_cte AS (
    SELECT stock_id,
           close AS last_price,
           timestamp::DATE AS date,
           LAG(close) OVER (PARTITION BY stock_id ORDER BY timestamp DESC) AS one_day_change
    FROM historical_prices 
    WHERE stock_id = 2
)
SELECT stock_id, last_price, date, one_day_change
FROM price_change_cte
WHERE date = (SELECT MAX(timestamp::DATE) FROM historical_prices WHERE stock_id = 2);

方式3:直接关联最新与次新记录(无需窗口函数)

如果只针对单个股票,也可以通过子查询找到最新和次新的记录进行关联:

SELECT 
    t1.stock_id,
    t1.close AS last_price,
    t1.timestamp::DATE AS date,
    t2.close AS one_day_change
FROM historical_prices t1
LEFT JOIN historical_prices t2 
    ON t1.stock_id = t2.stock_id 
    AND t2.timestamp = (
        SELECT MAX(timestamp) 
        FROM historical_prices 
        WHERE stock_id = t1.stock_id AND timestamp < t1.timestamp
    )
WHERE t1.stock_id = 2
    AND t1.timestamp = (SELECT MAX(timestamp) FROM historical_prices WHERE stock_id = 2);

方案对比

  • 方式1的ROW_NUMBER()写法最通用,支持同时查询多个股票的最新变动(只需去掉WHERE stock_id=2),逻辑清晰且性能稳定。
  • 方式2和3更适合单股票场景,写法也相对直观。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 15:01:05