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

Redshift中取上一个B为True的A值填充列C的SQL问题

解决Redshift中填充最近True对应ID的问题

首先明确需求:给test表新增列C,当B为False时,C取最近的B为True行的A值;当B为True时,C就是当前行的A值。

先分析你两个查询的错误原因:

  • 第一个查询问题:
    1. Redshift中B='T'返回布尔值,不能直接用SUM求和,需通过CASE转成数值1/0
    2. Redshift的UPDATE语法不支持直接JOIN,要改用FROM子句关联CTE或子查询
  • 第二个查询问题:Redshift不支持MySQL风格的用户变量(@tmp),这种递推逻辑必须用窗口函数实现

下面是适配Redshift的正确操作步骤:

步骤1:新增列C

先给test表添加C列,注意要和A字段的类型一致(比如A是INT,C就设为INT):

ALTER TABLE test ADD COLUMN C INT;

步骤2:更新C列的值

提供两种可行的写法:

写法一:用LAST_VALUE窗口函数(推荐,逻辑更直观)

利用LAST_VALUE结合IGNORE NULLS,直接向前取最近的非NULL值(当B为T时取A,否则留空,再填充最近的有效值):

UPDATE test
SET C = sub.previous_true_A
FROM (
    SELECT 
        A,
        LAST_VALUE(CASE WHEN B = 'T' THEN A END IGNORE NULLS) OVER (
            ORDER BY A 
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
        ) AS previous_true_A
    FROM test
) sub
WHERE test.A = sub.A;

写法二:修正分组思路

把布尔转成数值后分组,再取每组的最小A(即该组第一个True的A值),适配Redshift的UPDATE语法:

WITH cte1 AS (
    SELECT 
        A,
        SUM(CASE WHEN B = 'T' THEN 1 ELSE 0 END) OVER (ORDER BY A) AS group_no
    FROM test
),
cte2 AS (
    SELECT 
        A,
        MIN(A) OVER (PARTITION BY group_no) AS previous_true_A
    FROM cte1
)
UPDATE test
SET C = cte2.previous_true_A
FROM cte2
WHERE test.A = cte2.A;

执行前可以先把UPDATE换成SELECT验证结果是否正确,比如写法一可以先跑:

SELECT 
    A,
    B,
    LAST_VALUE(CASE WHEN B = 'T' THEN A END IGNORE NULLS) OVER (
        ORDER BY A 
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS previous_true_A
FROM test;

确认结果符合预期后再执行UPDATE操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 06:33:26