これは、プラットフォームに関する私の最初の投稿です。
この画像が私がやろうとしていることを説明していることを願っています。テーブルBをテーブルAにマージしようとしています。条件が満たされた場合(A.cell = B.cell AND A.object = B.objet)、A.costをテーブルBの対応するコストで更新します。条件が満たされない場合は、BからAに行を挿入します。
これまでに試したのはアップサートですが、機能しませんでした。
INSERT INTO reached_points
SELECT B.cell_id, B.object_id, B.reached_cost
FROM test_reached_cells B
ON CONFLICT (cell_id, object_id)
WHERE (cell_id = B.cell_id AND object_id = B.object_id)
DO UPDATE SET cost = B.reached_cost
CONFLICTの後のWHERE句で、その競合が「トリガーされる」ときに定義できると思いました。そうではありませんか?ドキュメントには「[ONCONFLICTtarget action;]ターゲットは次のようになります:WHERE述語–述語付きのWHERE句」のように書かれているのでそう思いました。
更新を実現する方法はありますか?条件が満たされない場合は挿入しますか?テーブルを2回比較するのは非効率的であると思われるため、2つの完全に別個のステップでそれを行うことは避けたかったのです。
CONFLICTの後のWHERE句で、その競合が「トリガーされる」ときに定義できると思いました。そうではありませんか?
いいえ。競合を定義するのはターゲット、つまりON CONFLICT
キーワードの直後に続く式です。クエリでは、次のようになります。
on conflict(cell_id, object_id)
...これが必要です-これには、この列のタプル(または主キー制約)に一意のインデックスが必要であることに注意してください。したがって、このwhere
句は必要ありません(または必要ありません)。
また、do update
句内の他のテーブルから列にアクセスするには、疑似テーブルを使用できますexcluded
。
考えてみましょう:
insert into reached_points(cell_id, object_id, cost)
select cell_id, object_id, reached_cost from test_reached_cells
on conflict(cell_id, object_id)
do update set cost = excluded.cost
サンプルデータ:
select * from reached_points;
cell_id | object_id | 費用 ------:| --------:| ---: 1 | 2 | 3
select * from test_reached_cells;
cell_id | object_id | リーチコスト ------:| --------:| -----------: 1 | 2 | 4 1 | 3 | 4
クエリ:
insert into reached_points(cell_id, object_id, cost)
select cell_id, object_id, reached_cost from test_reached_cells
on conflict(cell_id, object_id)
do update set cost = excluded.cost
-- 2 rows affected
結果:
select * from reached_points;
cell_id | object_id | 費用 ------:| --------:| ---: 1 | 2 | 4 1 | 3 | 4
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加