2012-12-05 214 views
1

我具有以下設置:複製數據的一列從一個表到另一PostgreSQL中

表1:

latdouble 
3 
4 
5 
1 
6 
2 
6 
9 

表2:

time latdouble(type double) latvarchar(type varchar) 
2:00        3 
3:00        4 
4:00        5 
5:00        1 
6:00        6 
7:00        2 
8:00        6 
9:00        9 

在表1基本上latdouble是在正確的順序,我想將它們的值複製到Table2中,結果應該是:

表2:

time latdouble(type double) latvarchar(type varchar) 
2:00 3       3 
3:00 4       4 
4:00 5       5 
5:00 1       1 
6:00 6       6 
7:00 2       2 
8:00 6       6 
9:00 9       9 

據我所知,我需要使用類似如下的命令:

update Table2 set latdouble = (select latdouble from Table1) 

不過,我得到以下錯誤:

ERROR: more than one row returned by a subquery used as an expression 

我肯定有一個簡單的修復,但我不明白,

謝謝, 詹姆斯

更新:讓我解釋一下這是如何發生的。表2最初看起來像:

表2:

time latvarchar(type varchar) 
2:00 3       
3:00 4       
4:00 5       
5:00 1       
6:00 6       
7:00 2       
8:00 6       
9:00 9 

我加入latdouble(雙型)柱,以表2。

然後我創建了一個名爲Table1的新表,其中包含一個名爲latdouble(type double)的列。我用下面的命令從表2投latvarchar並將其複製到表1:

insert into Table1 (latdouble) select cast(latvarchar as double precision) from Table2 

,現在我想的值複製從表1回latdouble參見表2 latdouble。我這樣做的原因是將latvarchar的值轉換爲double並將它們保存在latdouble中,而不必創建整個Table2的臨時副本,因爲它是一個包含幾個索引的非常大的表。

+0

不表1有一個排序主鍵?如果沒有,那麼你看到的'訂單'僅僅是發動機方面的便利。沒有什麼能阻止它在將來的查詢中以任何隨機順序顯示它......添加並向Table1填充一些列以指示您想要的排序順序,此時將有可能實現解決方案。 – PinnyM

+0

不,它沒有主鍵,但請您可以看到我添加的更新,它解釋了這種情況是如何產生的。我選擇創建Table1的方法是否意味着'訂單'不僅僅是方便? –

+0

沒有主鍵的表格(接近)沒有意義。 – wildplasser

回答

0

如果我理解正確,根本不需要使用Table1。您可以使用UPDATE簡單地設定各行的latdouble值到位:

UPDATE Table2 SET latdouble = cast(latvarchar as double precision); 

UPDATE

逐步做到這一點,我能想到的2個選項。直到沒有行被再更新

選項1(快速和骯髒)

UPDATE Table2 
SET latdouble = cast(latvarchar as double precision) 
WHERE tKey IN (SELECT tKey FROM Table2 WHERE latdouble IS NULL LIMIT 10000); 

運行很多次(這意味着沒有latdouble字段是NULL)

選項2。(使用光標和增量提交)

繼方法this article,您可以運行此Python腳本:

#!/home/postgres/python/bin/python 
# 
# incremental commits 
# 2008 kcg 

import psycopg2 
import time 

# vars 
incremental_commit_size=10000 # number of rows 
throttle_time=0   # seconds 

connectstr="host=localhost dbname=postgres user=postgres port=5432" 
handle=psycopg2.connect(connectstr) 
cursor=handle.cursor() 
cursor2=handle.cursor() 
sql="select tKey from table2" 
cursor.execute(sql) 

while 1: 

output = cursor.fetchmany(incremental_commit_size) 

if not output: 
    break 
for row in output: 

    # update table 
    sql="update table2 set latdouble = cast(latvarchar as double precision) where tKey = %s" 
    cursor2.execute(sql,([row[0]])) 

#commit, invoked every incremental commit size 
handle.commit() 
time.sleep(throttle_time) 

handle.commit() 
+0

謝謝,但是這不會在PostgreSQL中創建Table2的臨時副本嗎?在這種情況下臨時表會佔用更多的100GB ... –

+0

不,它根本不會創建任何臨時表。它只是用新值更新現有行。你有特定的理由相信嗎?使用簡單的UPDATE語句時,我從來沒有遇到過這樣的擔憂... – PinnyM

+0

爲了讓這個觀點更加強大 - 如果您的Table2上已經存在'latdouble'作爲'double precision',那麼數據庫已經分配了必要的空間爲了它。所以本專欄的更新不應該讓你的數據庫增長。它當然不應該需要任何臨時表(除了事務級別,在您使用的任何語句中無法避免)。 – PinnyM

相關問題