postgreSQL查询填充单列中的所有值



这可能听起来很基本,而且经常被问到,但我很惊讶这个问题经常只得到部分回答。

假设我有一个POSTGRESQL数据库,其中有一个名为"calculation"在一张叫做"表"的桌子上。

我有所有值来填充数据库外的计算。假设这些值在一个用逗号分隔的字符串中。现在我要构造一个SQL语句来改变"&;calculation&;"的所有值,按照它们出现在这样一个字符串中的顺序。

这里也有人问过类似的问题,互联网上有无数关于如何向数据库添加值的教程,但他们总是建议:

UPDATE calculation FROM table SET calculation=value WHERE ... 

这个命令的问题是:(1)它需要一个WHERE条件,而这个条件不存在(我们想要更新所有的值,而不仅仅是符合特定条件的值)。(2)假设只有一个值需要计算。因此,它似乎建议我们必须为每一行调用一个查询。

询问的人往往倾向于:

INSERT INTO table (calculation) VALUES ... 

,它完全符合语法,但无法工作,因为列已经在那里并且已经创建了行。

这是SQL之外的一个简单操作。R、python、matlab和其他语言通常能够将向量作为列附加到它们的表等价物上。或者,更好的是,用一个向量替换一个列的内容。我错过了什么?

编辑:更具体的例子:

假设数据库db中已经存在如下表,名称为"&;table&;

">
<表类>PKID名称计算tbody><<tr>1阿尔法空2β空3θ空

您想要执行一些使用ROW_NUMBER()窗口函数来创建基于顺序的记录之间的对应的东西:

WITH ValueList(Calculation) AS (
Values('akdak'),('dndja'),('jsnajna')
)
UPDATE MyTable
SET Calculation = V.Calculation
FROM (
SELECT Name, ROW_NUMBER() OVER (ORDER BY Name)
FROM MyTable
) T(Name, rownum)
JOIN (
SELECT Calculation, ROW_NUMBER() OVER (ORDER BY Calculation)
FROM ValueList
) V(Calculation, rownum)
ON T.rownum = V.rownum
WHERE MyTable.Name = T.Name

JOIN将使值计数不需要与表中的记录匹配。额外的值将被忽略,额外记录的calculation列将保持为空。

注意:我将WHERE MyTable.Name = T.Name放在查询的末尾,但根据哪些列是UNIQUE和/或NOT NULL以及您想要的精确行为,您可能更喜欢使用WHERE MyTable.PKID = T.PKID

根据接受的答案,似乎真正的问题是如何使用单个查询执行批量更新。

对于大量数据(数千个或更多),典型的解决方案是使用COPY将数据插入到staging表中,然后通过join ID值来更新目标表。因为主键是索引的,所以JOIN会很快:

UPDATE Target
Set 
Calculation1=staging.Calculation1,
...
FROM Source INNER JOIN Target
ON Source.ID=Target.ID

对于行数较少的情况,可以使用表值构造函数发出ID和新值:

UPDATE Target
Set 
Calculation1=staging.Calculation1,
...
FROM (
VALUES
(1, 'London'),
(2, 'Rio de Janeiro'),
(3, 'Tokyo')
) as Source(ID, Field1) 
INNER JOIN Target
ON Source.ID=Target.ID;