【问题标题】:Populate column with generated series使用生成的系列填充列
【发布时间】:2021-10-30 10:34:31
【问题描述】:

意外删除了 Postgres 中自动递增的主键 id 列中的信息,我的目标是用生成的一系列数据重新填充它。例如:

UPDATE mytable
SET id = (SELECT GENERATE_SERIES(1,3456))

这会引发错误: 错误:用作表达式的子查询返回多行

UPDATE mytable
SET id = SELECT a.n from generate_series(1, 3456) as a(n)

(抛出语法错误)

在 PostgreSQL 中使用生成的系列更新单个列的正确方法是什么?为什么SET 在这里不起作用?

【问题讨论】:

  • 错误来自 generate_series 返回许多行 - 所以你实际上是在尝试将 mytable 中每一行的 ID 设置为 generate_series 返回的多行。
  • 要从字面上回答您关于语法的问题,您需要将generate_series() 视为一个表,而不是一个值。 (注意,这不是你想要的,它只是避免语法错误) UPDATE mytable SET id = a.n FROM generate_series(1, 3456) AS a(n)。这不能满足您的要求的原因是仍然存在隐式笛卡尔积,WHERE 子句通常会避免这种情况; UPDATE mytable SET id = a.n FROM generate_series(1, 3456) AS a(n) WHERE mytable.something = a.something,不幸的是,您在 WHERE 子句中可以指出任何内容。

标签: sql postgresql insert sql-update


【解决方案1】:

如果你有主键,你可以这样做:

UPDATE mytable t
    SET id = new_id
    FROM (SELECT tt.*, ROW_NUMBER() OVER (ORDER BY id) as new_id
          FROM mytable tt
         ) tt
    WHERE t.id = tt.id;

【讨论】:

  • 这可能不起作用,因为 OP 似乎表明他们删除了 ID
【解决方案2】:

如果您删除了某些行的 id 列,想再次给它们一个 ID,而不关心 ID 是什么,您可以使用类似的东西:

UPDATE mytable 
SET id = nextval('mytable_id_seq')
WHERE id IS NULL

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-23
    • 2017-06-26
    • 1970-01-01
    • 2021-08-14
    • 2021-04-17
    • 2018-12-11
    • 1970-01-01
    • 2019-12-26
    相关资源
    最近更新 更多