有时,人们可能想将一些数据从一列移到另一列。通过 move (相反于复制),我的意思是在执行操作之前,新列最初为null,而在执行操作后,旧列应设置为null。

我有这样定义的表:
CREATE TABLE photos(id BIGSERIAL PRIMARY KEY, photo1 BYTEA, photo2 BYTEA);
假设表中有一个条目,其中photo1包含一些数据,而photo2NULL。我想对UPDATE进行查询,以使photo1变为NULL,并且photo2包含最初在photo1中的数据。

我发出以下SQL命令(为简洁起见,省略了WHERE子句):
UPDATE photos SET photo2 = photo1, photo1 = NULL;
看来行得通。

我也这样尝试过:
UPDATE photos SET photo1 = NULL, photo2 = photo1;
它似乎也起作用。

但是可以保证工作吗?具体来说,可以先将photo1设置为NULL,再将photo2设置为photo1,从而使我最后两列都使用NULL吗?

顺便说一句,当我的UPDATE很大时,这种标准的BYTEA语法似乎效率不高,因为必须通过简单的指针交换就可以从photo2逐字节复制photo1。也许有一种我不知道的更有效的方法?

最佳答案

这绝对是安全的。
UPDATE中的列引用是指旧列,而不是新值。实际上,没有任何方法可以引用另一列中的计算出的新值。

参见例如

CREATE TABLE x (a integer, b integer);
INSERT INTO x (a,b) VALUES (1,1), (2,2);

UPDATE x SET a = a + 1, b = a + b;

结果是
test=> SELECT * FROM x;
 a | b
---+---
 2 | 2
 3 | 4

...并且分配的顺序并不重要。如果您尝试乘以一个值,您将得到
test=> UPDATE x SET a = a + 1, a = a + 1;
ERROR:  multiple assignments to same column "a"

因为给定两个表达式都引用旧的元组值并且顺序不重要,所以多次分配同一列是没有意义的。

但是,为了避免在这种情况下重写整个表,我只需要ALTER TABLE ... ALTER COLUMN ... RENAME ...然后CREATE用旧名称替换新列。

关于sql - 在PostgreSQL中将数据从一列移到另一列,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44992802/

10-10 01:29