我有一个包含列(target
,id
)的大型value
表。我想将value='old'
更新为value='new'
。
最简单的方法是UPDATE target SET value='new' WHERE value='old';
但是,这会删除并创建新行,可能不建议这样做。所以我尝试进行合并列更新:
# staging
CREATE TABLE stage (LIKE target INCLUDING DEFAULTS);
INSERT INTO stage (SELECT id, value FROM target WHERE value=`old`);
UPDATE stage SET value='new' WHERE value='old'; # ??? how do you update value?
# merge
begin transaction;
UPDATE target
SET value = stage.value FROM stage
WHERE target.id = stage.id and target.distkey = stage.distkey; # collocated join?
end transaction;
DROP TABLE stage;
UPDATE
删除/写入。有没有办法在INSERT
?CREATE TABLE LIKE
?答案 0 :(得分:2)
您是否更新了表格中的所有行?
如果是,您可以使用CTAS(创建表格),这是推荐的方法
假设你的表看起来像这样
table1
id, col1,col2, value
您可以使用以下SQL创建新表
CREATE TABLE tmp_table AS
SELECT id, col1,col2, 'new_value'
FROM table1;
验证tmp_table中的数据后
DROP TABLE table1;
ALTER TABLE tmp_table RENAME TO table1;
如果您没有更新所有行,您可以使用过滤器来执行CTAS并将其余行插入新表中,如果是这种情况,请告诉我您是否需要更多信息
CREATE TABLE tmp_table AS
SELECT id, col1,col2, 'new_value'
FROM table1
WHERE value = 'old'
INSERT INTO tmp_table SELECT * from table1;
下一步是DROP tmp表并重命名table1
更新:根据您的评论,您可以执行以下操作,如果这样可以解决您的问题,请告诉我。
此方法基本上创建一个新表来替换现有表。 我已经使用了你的一些代码
CREATE TABLE stage (LIKE target INCLUDING DEFAULTS);
INSERT INTO stage SELECT id, 'new' FROM target WHERE value=`old`;
以上INSERT插入要使用' new'更新的行,之后无需运行UPDATE。
带来不变的行
INSERT INTO stage SELECT id, value FROM target WHERE value!=`old`;
在此之后,您有target
表,这是原始表格完整
stage
表将包含两组行,更新的行包含' new'您不想更改的值和行
将target
替换为stage
DROP TABLE target;
或保持进一步验证
ALTER TABLE target RENAME TO target_old;
ALTER TABLE stage RENAME TO target;
答案 1 :(得分:0)
来自红移开发者:
此案例不需要upsert或update + insert,只需运行更新即可:
UPDATE target SET value='new' WHERE value='old';
另一种方法是INSERT
您需要的行和DELETE
其他行,但这不必要地复杂。