我正在撰寫一些腳本來清理一些資料。因為我們無法復制生產資料庫,所以我們不得不以某種方式手動將一些測驗資料加載到兩個表中,這些表與生產中的表具有相同的結構和相同的資料分布。
我們使用 PostgreSQL 12.8
這些表很大,填充這兩個表需要付出很多努力。為了加速插入,我們洗掉了兩個表中的所有索引。在加載結束時,當我們想要重新創建索引時,我們發現意外地加載了一些資料兩次。
假設我們的表看起來像這樣:
table_1: table_2:
id id value
---- --------------
1 id-1 1 id-1 v-1
2 id-1 2 id-1 v-2
3 id-2 3 id-1 v-3
4 id-2 4 id-1 v-4
5 id-3 5 id-2 v-5
6 id-2 v-6
7 id-2 v-7
8 id-2 v-8
9 id-3 v-9
10 id-3 v-10
正如您table_1在行號 2) 和 4) 中看到的那樣,它們是重復的。我們想用別的東西代替它們;說id-4和id-5。我們如何計算新 ID 并不重要,它必須是唯一的。它可以是任何東西id-1-dedup,但對于獲得相同修復id-2-dedup的重復 ID 來說是非常重要的一半。table_2應用修復后,我希望我們的兩個表如下所示:
table_1: table_2:
id id value
---- --------------
1 id-1 1 id-1 v-1
2 id-4 2 id-1 v-2
3 id-2 3 id-4 v-3
4 id-5 4 id-4 v-4
5 id-3 5 id-2 v-5
6 id-2 v-6
7 id-5 v-7
8 id-5 v-8
9 id-3 v-9
10 id-3 v-10
哪一行獲得了新 ID 是無關緊要的,我們只想從中消除重復項table_1并反映其中的變化table_2。可惜合并陳述句在 PostgreSQL 12.8 中不可用
洗掉資料并重新插入它并不是一個真正的選擇,因為填充value列需要大量作業,如果沒有其他巧妙的方法,我們只會這樣做。
先感謝您。
uj5u.com熱心網友回復:
我將采用的方法是向兩個表中添加一個序列列。然后您可以運行以下更新:
WITH cte as
(SELECT serial_col, row_number() over(partition by id) as rn
FROM table_1)
UPDATE table_1
SET id = table_1.id || '-dup'
FROM cte
WHERE cte.serial_col = table_1.serial_col AND cte.rn = 2;
和
WITH cte as
(SELECT serial_col, row_number() over(partition by id) as rn
FROM table_2)
UPDATE table_2
SET id = table_2.id || '-dup'
FROM cte
WHERE cte.serial_col = table_2.serial_col AND cte.rn > 2;
請注意,這假定您只有重復項而沒有三次重復項。
運行更新后,您可以根據需要洗掉序列列。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/535298.html
下一篇:處理客戶端和服務器之間的時區
