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

Redshift SQL:如何实现同表自连接更新前一行对应字段数据?

Fixing Self-Join Update Issue in Redshift for Tab Table

Got it, let's work through this Redshift update problem. The self-join approach you tried (UPDATE tab SET tab.fieldA = tabPrior.fieldA FROM tab tabPrior WHERE tab.version = tabPrior.version + 1) won't work here because Redshift—being an MPP columnar database—restricts modifying a table while reading from it in the same statement. This is to maintain data consistency across its distributed nodes.

Here are two reliable methods to achieve your goal:

Method 1: Use the LAG() Window Function with a CTE

The LAG() window function is perfect for grabbing the previous row's value directly, no self-join needed. We'll first compute all the prior fieldA values in a CTE, then join that back to the original table for the update:

WITH prior_field_values AS (
    SELECT
        version,
        -- Get fieldA from the row with version = current version - 1
        LAG(fieldA) OVER (ORDER BY version) AS prior_fieldA
    FROM tab
)
UPDATE tab
SET fieldA = pfv.prior_fieldA
FROM prior_field_values pfv
WHERE tab.version = pfv.version
-- Exclude the first row (it has no prior row, so LAG returns NULL)
AND pfv.prior_fieldA IS NOT NULL;

Why this works:

The CTE runs first, calculating all the prior values in a single pass over the table. Then we join this precomputed dataset to the original table for the update—Redshift handles this safely because we're no longer reading and modifying the same table in the same step.

Method 2: Use a Temporary Table (Great for Large Datasets)

If you're working with a huge table, using a temporary table can be more efficient since Redshift optimizes temp table operations. Here's how:

-- Create a temp table to store each version and its prior fieldA value
CREATE TEMP TABLE tab_prior_data AS
SELECT
    version,
    LAG(fieldA) OVER (ORDER BY version) AS prior_fieldA
FROM tab;

-- Perform the update by joining the temp table to the original
UPDATE tab
SET fieldA = tpd.prior_fieldA
FROM tab_prior_data tpd
WHERE tab.version = tpd.version
AND tpd.prior_fieldA IS NOT NULL;

-- Optional: Temp tables auto-drop when your Redshift session ends, but you can manually clean up
DROP TABLE IF EXISTS tab_prior_data;

Why this works:

Temporary tables are stored locally on each node, so joining against them avoids the distributed read/write conflict that comes with self-joining the original table during an update.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:13:18