PostgreSQLでRETURNINGとON CONFLICTを使ってUPSERTを行う方法

2024-04-02

PostgreSQLでRETURNINGとON CONFLICTを使ってUPSERTを行う方法

RETURNING句は、INSERTステートメントによって実際に挿入された(またはON CONFLICT DO UPDATE句によって更新された)各行に基づいて計算された値を返すために使用されます。これは、通番のシーケンス番号など、デフォルトで与えられた値を取り出す時に主に便利です。

RETURNINGとON CONFLICTを組み合わせることで、UPSERT操作を行い、同時に挿入された(または更新された)レコードの情報を取得することができます。

以下の例では、usersテーブルに新しいユーザーを挿入しようとしています。ユーザー名がすでに存在する場合は、そのユーザーの情報を更新します。

INSERT INTO users (username, email)
VALUES ('johndoe', '[email protected]')
ON CONFLICT (username)
DO UPDATE SET email = '[email protected]'
RETURNING id, username, email;

この例では、以下の結果が返されます。

id | username | email
------- | -------- | --------
123 | johndoe | [email protected]

RETURNING句によって、挿入された(または更新された)レコードのidusernameemailを取得することができます。

RETURNING句で取得できる値は以下の通りです。

  • INSERTされた列の値
  • 更新された列の値
  • RETURNING句で指定した式

RETURNING句を使用する際の注意点

  • RETURNING句を使用するには、RETURNINGで使用するすべての列に対するSELECT権限が必要です。
  • ON CONFLICT DO UPDATEはまた、その式あるいはconditionで読み取られるすべての列についてのSELECT権限も必要です。

RETURNINGとON CONFLICTを組み合わせることで、PostgreSQLでUPSERT操作を簡単に行うことができます。




-- usersテーブル
CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  username VARCHAR(255) UNIQUE NOT NULL,
  email VARCHAR(255) NOT NULL
);

-- 新しいユーザーを挿入
INSERT INTO users (username, email)
VALUES ('johndoe', '[email protected]')
ON CONFLICT (username)
DO UPDATE SET email = '[email protected]'
RETURNING id, username, email;
id | username | email
------- | -------- | --------
123 | johndoe | [email protected]
  • 複数の列を更新する
INSERT INTO users (username, email)
VALUES ('janedoe', '[email protected]')
ON CONFLICT (username)
DO UPDATE SET email = '[email protected]',
              last_login = CURRENT_TIMESTAMP
RETURNING id, username, email, last_login;
  • 式を使用して値を返す
INSERT INTO users (username, email)
VALUES ('johndoe', '[email protected]')
ON CONFLICT (username)
DO UPDATE SET email = '[email protected]',
              last_login = CURRENT_TIMESTAMP
RETURNING id, username, email, last_login - INTERVAL '1 hour' AS adjusted_last_login;



PostgreSQLでUPSERTを行うその他の方法

MERGE文

MERGE INTO users
USING (
  SELECT 'johndoe' AS username, '[email protected]' AS email
) AS t
ON users.username = t.username
WHEN MATCHED THEN
  UPDATE SET email = t.email
WHEN NOT MATCHED THEN
  INSERT (username, email) VALUES (t.username, t.email);

この例では、usersテーブルにjohndoeというユーザーが存在するかどうかを確認します。

  • 存在する場合は、email[email protected]に更新します。
  • 存在しない場合は、johndoeというユーザーを[email protected]というメールアドレスで挿入します。

UPDATE文とCASE式を使用してUPSERTを行うこともできます。

UPDATE users
SET email = '[email protected]'
WHERE username = 'johndoe';

INSERT INTO users (username, email)
SELECT 'johndoe', '[email protected]'
WHERE NOT EXISTS (
  SELECT 1 FROM users WHERE username = 'johndoe'
);

この例では、まずusersテーブルを更新し、usernamejohndoeのユーザーのemail[email protected]に設定します。

  • 更新に成功した場合は、何も行いません。
  • 简单的なUPSERT操作の場合は、INSERT ON CONFLICT文を使用するのが最も簡単です。
  • 複雑なUPSERT操作の場合は、MERGE文を使用すると、より柔軟な方法で操作を行うことができます。
  • 既存のコードを変更したくない場合は、UPDATE文とCASE式を使用することができます。

PostgreSQLでUPSERTを行う方法はいくつかあります。どの方法を使用するべきかは、状況によって異なります。


sql postgresql upsert


SQL Server Management Studioで列の値をNULLにする3つの方法

SQL Server Management Studio (SSMS) は、Microsoft SQL Server データベースを管理するためのツールです。このツールを使用して、テーブルの列の値をNULLに設定することができます。方法SSMSで列の値をNULLに設定するには、いくつかの方法があります。以下に、最も一般的な方法をいくつか紹介します。...


MySQL、SQL、MariaDBでグループ化に基づいて1つの値を選択する方法

このチュートリアルでは、MySQL、SQL、MariaDBで、複数の列に基づいてグループ化し、グループ内の1つの値を選択する方法について説明します。これは、さまざまなシナリオで役立つ一般的なタスクです。例題従業員のテーブルがあり、department_id と salary という2つの列があるとします。各部門で最も高い給料を知りたい場合は、次のクエリを使用できます。...


CREATE TABLE AS ... SELECT ...でシンプルに復元

前提条件PostgreSQL 9.1以降を使用していること移動先のスキーマが存在することテーブルに対する十分な権限を持っていること手順以下のコマンドを実行して、テーブルを移動先のスキーマに設定します。table_name は移動対象のテーブル名に置き換えます。...


Vagrantで立ち上げたPostgreSQLにpsqlで接続できない!?「Psql could not connect to server: No such file or directory, 5432 error」エラーの解決方法

Vagrantで立ち上げたPostgreSQLにpsqlコマンドで接続しようとすると、以下のエラーが発生します。原因このエラーは、以下のいずれかの原因で発生します。PostgreSQLサーバーが起動していないVagrantの設定が間違っている...


MySQL、SQL、MariaDB で INSERT ステートメントを使って複数行挿入し、LAST_INSERT_ID() や RETURNING 句、トリガーを使って ID を取得する方法

MySQL、SQL、MariaDB などのデータベースで、INSERT ステートメントを使用して複数の行を挿入する場合、挿入された各行の ID を取得する方法があります。方法LAST_INSERT_ID() 関数を使用するこの関数は、最後に挿入された行の ID を返します。複数の行を挿入する場合、最後に挿入された行の ID のみ取得できます。...


SQL SQL SQL SQL Amazon で見る



information_schemaビューを使ってテーブル情報を取得する

PostgreSQLには、テーブルの構造や属性情報を表示する「DESCRIBE TABLE」コマンドは存在しません。しかし、いくつかの代替方法を用いて、同様の情報を得ることができます。代替方法psqlコマンドの\dオプションを使用することで、テーブルの構造情報を表示できます。 例: \d テーブル名 出力例: Name | Type | Modifier | Description ------- | -------- | -------- | -------- id | integer | not null | name | text | | created_at | timestamp without time zone | |


MERGEステートメントによるUPSERT:PostgreSQLとSQL Server

従来のINSERTとREPLACEの制限INSERT: 主キーが重複するとエラーが発生します。 既存のレコードを更新できません。主キーが重複するとエラーが発生します。既存のレコードを更新できません。REPLACE: 存在しない場合は新しいレコードを作成します。


FETCH FIRST n ROWS ONLY句を使用してOracleクエリで結果を制限する方法

Oracleデータベースで、ORDER BY句を使用した後に返される行数を制限するには、いくつかの方法があります。方法ROWNUM疑似列を使用するROWNUM疑似列は、各行の相対的な行番号を格納します。この列を使用して、結果セット内の特定の行範囲を選択できます。


PostgreSQLのテーブル操作に関するトラブルシューティング

\dtコマンドを使用するこれは、PostgreSQLのpsqlコマンドラインツールでテーブルを表示する最も簡単な方法です。以下のコマンドを実行します。このコマンドは、現在のデータベースにあるすべてのテーブルの名前、所有者、作成日時、およびその他の情報を表示します。


PostgreSQLデータベースの初期化:すべてのテーブルを削除して元に戻す

DROP TABLE コマンドを使用するこれは、個々のテーブルをドロップする最も簡単な方法です。すべてのテーブルをドロップするには、以下のコマンドを使用します。ここで、table_name はドロップしたいテーブルの名前です。例:複数のテーブルをまとめてドロップするには、カンマで区切ることができます。


データ量、構造、パフォーマンス要件… これさえあれば完璧!階層データ保存方法の選び方

親子関係テーブル最も単純な方法は、親子関係を表すテーブルを作成する方法です。このテーブルには、親ノードと子ノードのID、およびその他の属性を格納します。例:この例では、categoriesテーブルには、カテゴリID、名前、親カテゴリIDという3つの列があります。


PostgreSQL: INSERT INTO ... SELECT ... FROM ... WHERE NOT EXISTS ... を使う

PostgreSQL 9.5 以降では、INSERT . .. ON CONFLICT 構文を使用して、レコードが存在しない場合のみ INSERT することができます。ON CONFLICT 句で、競合が発生した場合の処理を指定します。DO NOTHING は、競合が発生した場合、何もせずに処理を終了します。


迷ったらコレ!PostgreSQLでNULLカラムを含むユニーク制約のベストプラクティス

PostgreSQLでNULLカラムを含むユニーク制約を作成するには、いくつかの方法があります。方法1: UNIQUE制約とデフォルト値の組み合わせこの例では、emailカラムにUNIQUE制約とデフォルト値'unknown'を設定しています。


PostgreSQL コマンドラインユーティリティ psql の使い方

この解説では、psqlから正常に終了するための方法を、分かりやすく日本語で説明します。\q コマンドを使用するpsqlから終了する最も簡単な方法は、\qコマンドを使用することです。このコマンドは、psqlを即座に終了し、オペレーティングシステムのプロンプトに戻ります。


pgAdmin IIIでPostgreSQLユーザーのパスワードを変更する方法

方法1:psqlコマンドを使用するこの方法は、PostgreSQLサーバーに直接接続してパスワードを変更する方法です。PostgreSQLサーバーに接続します。ALTER USERコマンドを使用して、パスワードを変更します。例:ユーザー名 "postgres" のパスワードを "newpassword" に変更する場合


PostgreSQLでUPSERT(MERGE、INSERT ... ON DUPLICATE UPDATE)を実行する方法

PostgreSQLでは、UPSERTを実現する方法はいくつかあります。INSERT . .. ON DUPLICATE UPDATEMERGEこの方法では、INSERTとON DUPLICATE UPDATEを組み合わせて、レコードが存在するかどうかをチェックします。


PostgreSQLでCTEを使用して3つのテーブルに一度にデータを挿入する方法

PostgreSQLでは、CTE (Common Table Expression)と呼ばれる機能を使用して、複雑なクエリをより読みやすく、メンテナンスしやすいモジュール化された部分に分割することができます。CTEを使用して、3つのテーブルに一度にデータを挿入することもできます。


PostgreSQLで柔軟なUPSERTを実現:複数競合ターゲットの仕組みとサンプルコード

従来のON CONFLICT句では、1つの列のみを競合ターゲットとして指定できましたが、PostgreSQL 9.5以降では、複数列を同時に競合ターゲットとして指定できるようになりました。これにより、より柔軟で高度なUPSERT処理が可能になります。


PostgreSQL 9.5の新機能「INSERT ON CONFLICT UPDATE」を使いこなす

この構文では、excludedという特別なテーブルを利用できます。これは、衝突によって挿入または更新されなかった行の値を含む仮想テーブルです。例:この例では、usersテーブルにJohn Doeという名前とjohndoe@example. comというメールアドレスを持つレコードが存在しない場合は挿入し、存在する場合はnameとemailを更新します。