在PostgreSQL中将一列数据从一个表复制到另一个表

时间:2012-12-05 15:12:19

标签: sql sql-update

我有以下设置:

表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

Table1中的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(type double)列添加到Table2。

然后我创建了一个名为Table1的新表,其中包含一个名为latdouble(double类型)的列。我使用以下命令从Table2转换latvarchar并将其复制到Table1:

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

现在我想将值从Table1 latdouble复制回Table2 latdouble。我这样做的原因是将值从latvarchar转换为double并将它们保存在latdouble中,而不必创建整个Table2的临时副本,因为它是一个包含少量索引的非常大的表。

1 个答案:

答案 0 :(得分:0)

如果我理解正确,根本不需要使用Table1。您可以使用UPDATE:

为每一行设置latdouble
UPDATE Table2 SET latdouble = cast(latvarchar as double precision);

<强>更新

要逐步执行此操作,我可以考虑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()