有时,人们可能想将一些数据从一列移到另一列。通过 move (相反于复制),我的意思是在执行操作之前,新列最初为null,而在执行操作后,旧列应设置为null。
我有这样定义的表:CREATE TABLE photos(id BIGSERIAL PRIMARY KEY, photo1 BYTEA, photo2 BYTEA);
假设表中有一个条目,其中photo1
包含一些数据,而photo2
是NULL
。我想对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/