質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Q&A

解決済

3回答

965閲覧

PostgreSQL 同じテーブルの前の値でINSERTしたいがサブクエリが多い

person

総合スコア224

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

0グッド

0クリップ

投稿2023/08/10 01:36

psql (PostgreSQL) 14.1

実現したいこと

別のレコードを参照して、
レコードが存在すればその値を使う。
レコードが無ければ任意の値を入れる。
ただし、カラムはnot null。

下に記載の構造のテーブルのため、
WHEREで指定したidのレコードのデータを使ってInsertする。

INSERT INTO test VALUES ( 4, CASE WHEN (SELECT val1 FROM test WHERE id = 1) IS NULL THEN 'nullでした' ELSE (SELECT val1 FROM test WHERE id = 1) END, CASE WHEN (SELECT val2 FROM test WHERE id = 1) IS NULL THEN 'nullでした' ELSE (SELECT val2 FROM test WHERE id = 1) END );

上記で実現はできましたが、
同じまたは似た内容のサブクエリが複数出てきていました。
極力無駄な参照は避けたいのですが、どのように改善すれば良いですか?

前提

テーブルの構造

-- Table: public.test -- DROP TABLE IF EXISTS public.test; CREATE TABLE IF NOT EXISTS public.test ( id integer NOT NULL, val1 text COLLATE pg_catalog."default" NOT NULL, val2 text COLLATE pg_catalog."default" NOT NULL, CONSTRAINT test_pkey PRIMARY KEY (id) ) TABLESPACE pg_default; ALTER TABLE IF EXISTS public.test OWNER to postgres;

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

with句(CTE 共通テーブル式)を使うのはどうでしょうか。

動くか試してませんが、サブクエリに「x」という名前をつけ先に取得します。

sql

1WITH x AS ( 2 SELECT val1,val2 FROM test WHERE id = 1 3) 4INSERT INTO test VALUES ( 5 4, 6 COALESCE((SELECT val1 FROM x),'nullでした'), 7 COALESCE((SELECT val2 FROM x),'nullでした') 8);

SELECTを減らしたいならNULLチェックもwith句に移動します。

sql

1WITH x AS ( 2 SELECT 3 COALESCE(val1,'nullでした') as v1, 4 COALESCE(val2,'nullでした') as v2 5 FROM test WHERE id = 1 6) 7INSERT INTO test SELECT 4,x.v1,x.v2 FROM x;

投稿2023/08/10 03:24

編集2023/08/11 01:35
hqf00342

総合スコア394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

まだ工夫の余地がありそうですが、たとえば以下のようなSQLで実現可能だと思います。

SQL

1INSERT INTO test 2SELECT new_id, COALESCE(T.val1, 'nullでした'), COALESCE(T.val2, 'nullでした') 3FROM (VALUES (4, 1)) AS X(new_id, old_id) 4LEFT OUTER JOIN test AS T ON X.old_id = T.id;

投稿2023/08/10 03:22

編集2023/08/10 03:22
neko_the_shadow

総合スコア2374

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

SQL

1CASE 2 WHEN (SELECT val1 FROM test WHERE id = 1) IS NULL THEN 'nullでした' 3 ELSE (SELECT val1 FROM test WHERE id = 1) 4END,

はこうできませんか?

SQL

1COALESCE((SELECT val1 FROM test WHERE id = 1),'nullでした'),

投稿2023/08/10 01:47

yambejp

総合スコア117674

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

person

2023/08/10 01:51 編集

NULL置換の関数の存在を忘れてました・・・。 ありがとうございます。 同じテーブルをの異なるカラムを同じ条件で見ている部分はサブクエリ分かれていてもそれほど問題ないですかね?(val1とval2のSELECT)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問