更新 row_number() 不起作用,为什么?

Update with row_number() not working, why?

我有以下 table:

CREATE TABLE t_overview
(
  obj_uid uuid,
  obj_parent_uid uuid,
  obj_no integer,
  obj_text text,
  obj_path text,
  isdir integer,
  intid bigint,
  intparentid bigint
)

我想从 uuid 移动到 bigint 并创建了新列 intidintparentid。我需要 intid 的唯一整数(obj_uid 是主键),所以我只想用 row_number() over (order by ...).

更新

似乎没有用。所以我尝试将结果写入临时 table,并通过连接更新。但是我得到了 1intid.

但是当我 select 从连接进行更新时,我得到 1、2、3、4、5、6 等。我错过了什么?

DROP TABLE IF EXISTS mytable;
CREATE TEMP TABLE mytable AS
WITH CTE AS 
(
    SELECT obj_uid, obj_parent_uid, obj_no
        , obj_text, obj_path, isdir
        , intid as cteIntId
        , intparentid as cteParentId
        , row_number() over (order by obj_uid) as rn 
    FROM T_Overview 
)
SELECT * FROM CTE;

UPDATE T_Overview SET intid = mytable.rn 
FROM T_Overview AS bt 
INNER JOIN mytable 
    ON mytable.obj_uid = bt.obj_uid 


-- UPDATE T_Overview SET intid = CTE.rn FROM CTE;
-- UPDATE T_Overview SET intparentid = CTE.intid FROM CTE;

你的更新有误,T_Overview与(T_Overview + mytable)没有关系。

这个应该有效:

UPDATE T_Overview SET intid = mytable.rn 
FROM mytable 
WHERE mytable.obj_uid = T_Overview.obj_uid;

Offtopic:你的 CTE 没有多大意义,一个简单的 SELECT 会给你同样的结果。

已经为您的错误提供了解释。

但你根本不需要临时 table:

BEGIN;
LOCK T_Overview;  -- if there is concurrent write access

WITH cte AS (
   SELECT obj_uid, obj_parent_uid
        , row_number() OVER (ORDER BY obj_uid) AS intid
   FROM   T_Overview 
   )
UPDATE  T_Overview t
SET     intid       = upd.intid 
      , intparentid = upd.intparentid
FROM   (
   SELECT t1.*, t2.intid AS intparentid
   FROM   cte t1
   LEFT   JOIN cte t2 ON t2.obj_uid = t1.obj_parent_uid
   ) upd
WHERE t.obj_uid = upd.obj_uid;

COMMIT;

只有在可以并发写入访问时才需要事务包装器和显式锁。 (对于临时 table 更是如此,中间有一个 更大的时间段。)

假设参照完整性 - 从 T_Overview.obj_parent_uidT_Overview.obj_uid 的 FK 约束。 obj_parent_uid 中的 NULL 值在 intparentid.

中转换为 NULL