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

PostgreSQL如何同表二次查询筛选出用户存款金额下降的记录

错误原因说明

SQL的执行顺序中,WHERE子句的执行优先级高于窗口函数计算、以及SELECT阶段的别名定义,所以你直接在WHERE中引用窗口函数生成的pre_deposit别名时,这个字段还没被计算出来,自然会提示不存在。

方案选择说明

你提到的四个选项里,left-join(左连接)是唯一适配该需求的选项,但它并不是这个场景的最优解:

  • union的作用是合并多个查询的结果集,完全不满足对比同用户前后存款的需求
  • right-join、outer-join 要么会生成大量无用的空值记录,要么逻辑冗余,没有使用必要

最优实现方案(无需二次查表)

直接用子查询或者CTE(公共表表达式)包裹带窗口函数的逻辑,在外层加过滤条件即可,性能比关联查询更好,逻辑也更简洁:

WITH customer_with_prev AS (
    SELECT person_id, 
           employee_id,
           deposit,
           ts,
           lag(deposit) OVER client_window AS pre_deposit
    FROM customer 
    WINDOW client_window AS (PARTITION BY person_id ORDER BY ts)
)
SELECT person_id, employee_id, deposit, ts
FROM customer_with_prev
WHERE pre_deposit > deposit;

执行后即可得到你期望的输出结果。


左连接实现方案(符合你要求的同表二次查询逻辑)

如果你必须用同表二次查询的方式实现,左连接的写法如下:

SELECT c1.person_id, c1.employee_id, c1.deposit, c1.ts
FROM customer c1
LEFT JOIN customer c2 
  ON c1.person_id = c2.person_id 
  AND c2.ts = (
      SELECT MAX(ts) FROM customer c3 
      WHERE c3.person_id = c1.person_id AND c3.ts < c1.ts
  )
WHERE c2.deposit > c1.deposit;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 19:45:05