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

PostgreSQL问题:无法将查询结果作为新列写入已有表

解决PostgreSQL更新列时子查询返回多行的问题

错误原因

你之前的UPDATE语句中,赋值用的子查询返回了表中所有行的结果,数据库无法确定每一行对应哪个值,因此抛出ERROR: subquery returns more than 1 row错误。

解决方案

方案1:直接在SET语句中内联计算逻辑

不需要嵌套子查询,直接为每行计算对应的date_day值:

UPDATE "CUSTOM".org 
SET date_day = LEFT(
    CASE
        WHEN dt !~ '^[0-9]' THEN RIGHT(dt, strpos(dt, ',') + 12)
        ELSE dt
    END,
    strpos(
        CASE
            WHEN dt !~ '^[0-9]' THEN RIGHT(dt, strpos(dt, ',') + 12)
            ELSE dt
        END,
        ' '
    ) - 1
);

方案2:通过主键/唯一键关联子查询

如果表有主键(比如id),可以用子查询生成带主键的结果集,再关联主表更新,确保每行对应正确的值:

UPDATE "CUSTOM".org o
SET date_day = orgi.day_
FROM (
    SELECT 
        id, -- 替换成你的表主键列
        LEFT(
            CASE
                WHEN dt !~ '^[0-9]' THEN RIGHT(dt, strpos(dt, ',') + 12)
                ELSE dt
            END,
            strpos(
                CASE
                    WHEN dt !~ '^[0-9]' THEN RIGHT(dt, strpos(dt, ',') + 12)
                    ELSE dt
                END,
                ' '
            ) - 1
        ) AS day_
    FROM "CUSTOM".org
) AS orgi
WHERE o.id = orgi.id; -- 主键关联

如果表没有主键,可以临时用PostgreSQL内部的ctid字段关联(仅临时更新使用,不建议依赖该字段长期操作):

UPDATE "CUSTOM".org o
SET date_day = orgi.day_
FROM (
    SELECT 
        ctid,
        LEFT(
            CASE
                WHEN dt !~ '^[0-9]' THEN RIGHT(dt, strpos(dt, ',') + 12)
                ELSE dt
            END,
            strpos(
                CASE
                    WHEN dt !~ '^[0-9]' THEN RIGHT(dt, strpos(dt, ',') + 12)
                    ELSE dt
                END,
                ' '
            ) - 1
        ) AS day_
    FROM "CUSTOM".org
) AS orgi
WHERE o.ctid = orgi.ctid;

方案3:使用生成列(自动维护,PostgreSQL 12+支持)

如果你的PostgreSQL版本在12及以上,可以创建存储生成列,让date_day自动随dt列更新,不需要手动执行UPDATE:

-- 先删除之前新增的空列(如果已添加)
ALTER TABLE "CUSTOM".org DROP COLUMN IF EXISTS date_day;

-- 创建生成列
ALTER TABLE "CUSTOM".org 
ADD COLUMN date_day text GENERATED ALWAYS AS (
    LEFT(
        CASE
            WHEN dt !~ '^[0-9]' THEN RIGHT(dt, strpos(dt, ',') + 12)
            ELSE dt
        END,
        strpos(
            CASE
                WHEN dt !~ '^[0-9]' THEN RIGHT(dt, strpos(dt, ',') + 12)
                ELSE dt
            END,
            ' '
        ) - 1
    )
) STORED;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 06:30:51