1

我有如下表:更新row_number()不起作用,爲什麼?

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。我需要一個唯一的整數(obj_uid是主鍵)intid,所以我只想更新row_number() over (order by ...)

似乎沒有工作。所以我嘗試將結果寫入臨時表,並通過連接進行更新。但我每intid得到1

但是,當我從更新的連接中選擇,我得到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; 
+0

'obj_parent_uid'是一個自引用(引用't_overview'本身),對吧? – 2015-03-02 08:29:38

+0

@Erwin Brandstetter:正確 – 2015-03-02 16:49:10

回答

2

@Frank已經爲您的錯誤提供瞭解釋。

但你並不需要臨時表在所有:

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; 

事務包裝和明確的鎖時,才需要,如果有可能併發寫訪問。 (更差的一個臨時表,在這裏你有之間的更大的時間段。)

假設的完整性 - 一個FK約束從T_Overview.obj_parent_uidT_Overview.obj_uidobj_parent_uid中的NULL值在intparentid中被轉換爲NULL。

2

你的更新是錯誤的,有T_Overview和(T_Overview + MYTABLE)之間沒有關係。

這一個應該工作:

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

Offtopic:您的CTE沒有多大意義,一個普通的選擇會給你同樣的結果。

+0

嗯,非常有趣。是的,這是真的。當我遇到麻煩時,我開始製作不必要的CTE。看起來PG做了一個隱式的交叉連接,更新表和from表是兩個不同的實體。這就解釋了爲什麼我在語法化之前遇到問題,直到將表從別名中除名。很奇怪......這是標準的SQL,還是這是一個PostGre奇怪? – 2015-03-02 19:15:48