2016-09-03 11 views
0

idを新しい値に置き換える必要があるテーブルt1があります。PostgreSQL:なぜこのアップデートが正しく動作しないのですか?

第2テーブルt_changesには、置換 old_id-> new_idが含まれています。 しかし私がUPDATEを行うとき、t1はすべてのレコードに対して同じ新しいID値を含んでいます。 何が間違っていますか? 同じ更新プログラムがT-SQLで正常に機能します。

drop table t1; 
drop table t2; 
drop table t_changes; 

create table t1 
(id INT,name text, new_id INT default(0)); 

create table t_changes 
(old_id INT,new_id int) 

insert into t1(id,NAME) 
VALUES (1,'n1'),(2,'n2'),(3,'n3'); 

insert into t_changes(old_id,new_id) 
values(1,11),(2,12),(3,13),(4,13) 

select * from t1; 
select * from t_changes; 

-------!!!! 
update t1 
set new_id = n.new_id 
from t1 t 
inner join t_changes n 
on n.old_id=t.id; 

select * from t1 
------------------------------ 
"id" "name" "new_id" 
----------------- 
"1" "n1" "11" 
"2" "n2" "11" 
"3" "n3" "11" 

答えて

1

はこれがある、あなたのPostgres update声明:

update t1 
    set new_id = n.new_id 
    from t1 t inner join 
     t_changes n 
     on n.old_id = t.id; 

問題がupdatet1fromに異なるt1を参照していることです。あなたは彼らが同じ参照であることを意図しています。あなたはこれを行うことができます。

update t1 
    set new_id = n.new_id 
    from t_changes n 
    where n.old_id = t.id; 

あなたの構文は(SQL Serverなど)いくつかの他のデータベースでサポートされている構文にかなり近いです。しかし、彼らのために、あなたはアップデートで表別名を使用する必要があります:

update t 
    set new_id = n.new_id 
    from t1 t inner join 
     t_changes n 
     on n.old_id = t.id; 
+0

[OK]を、のthnx。あなたが正しいです。私はSQL ServerのビジネスロジックをPostgreSQLに移植しており、それがそのような問題の原因です。この文はT-SQLで動作しますが、PostgreSQLでは期待通りに動作しません。このようなすべての更新プログラムを確認する必要があります。 – Oleg

+0

@Oleg:これは[マニュアルに記載されています](https://www.postgresql.org/docs/current/static/sql-update.html#AEN88864): "*ターゲットテーブルは、 from_list、自己参加を希望しない限り* " –

+0

@Oleg。 。 。 't1'は' FROM'節に 't'のエイリアスが与えられているので、あなたのクエリはSQL Serverでも正しく動作しませんでした。 'UPDATE'はエイリアスの代わりにテーブル名を使用しています(おそらくあなたの実際のクエリにはこの問題はありません)。 –

1

どう代わりにこれを行うことについて:t1でいくつかの行のt_changesには対応する行が存在しない場合、これはNULLt1.new_idを変更すること

update t1 
set new_id = (SELECT new_id FROM t_changes WHERE old_id=id); 

注意を。

関連する問題