「returning」句は挿入されていないソース列を返すことができますか?


14

これが私の実世界の問題の最小限の例です:

create table t(id serial primary key, rnd double precision);

もちろん、挿入した列をreturning句で返すことができます:

with w as (insert into t(rnd) values(random()) returning *)
insert into t(rnd) select random() from w returning *;
/*
| ID |            RND |
|----|----------------|
|  9 | 0.203221440315 |
*/

リテラルを返すこともできます:

with w as (insert into t(rnd) values(random()) returning *)
insert into t(rnd) select random() from w returning *, 1.0 dummy;
/*
| ID |            RND | DUMMY |
|----|----------------|-------|
| 11 | 0.594980469905 |     1 |
*/

ただし、ソース列を返すことはできません。

with w as (insert into t(rnd) values(random()) returning *)
insert into t(rnd) select random() from w returning *, w.rnd;
/*
ERROR: missing FROM-clause entry for table "w": with w as (insert into t(rnd) values(random()) returning *) insert into t(rnd) select random() from w returning *, w.rnd
*/

w.rnd最終returning節から抜け出す方法はありますか?

db <> fiddle here


MS SQL Serverでは、MERGEステートメントのみで追加の列を返すことができます。たぶんそれはpostgresでも機能するでしょう。
セバスチャンマイネ

SOに関するこの関連の回答で同様の問題UPDATEを解決しましが、これはうまくいきませんINSERT
アーウィンブランドステッター

回答:


12

RETURNING条項の文書には次のように書かれています。

各行が挿入された後にINSERTコマンドによって計算されて返される式。この式では、table_nameで指定されたテーブルの任意の列名を使用できます。*を書き込んで、挿入された行のすべての列を返します。

これは明らかに、他のテーブルの列には適用されません。

私は実際に問題のポイントを取得していませんが(つまり、なぜあなたはこれを行うのですか-それは元のものの少し抽象的なバージョンだからだと思います)、可能な解決策は次のとおりです:

WITH w AS (INSERT INTO t(rnd) VALUES (random()) RETURNING *),
     x AS (INSERT INTO t(rnd) SELECT random() FROM w RETURNING *)
SELECT w.rnd, x.rnd
  FROM w, x;

つまり、複数の書き込み可能なCTEをクエリの先頭に配置できます。dbfiddleの実際の動作をご覧ください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.