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

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

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

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

Q&A

解決済

1回答

4124閲覧

データが既に存在していないかチェックし、 存在していない場合、そのテーブルのIDの最大値に1足した値で登録したい。

acre_maker

総合スコア145

PostgreSQL

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

0グッド

0クリップ

投稿2016/09/12 05:17

###前提・実現したいこと
データが既に存在していないかチェックし、
存在していない場合、そのテーブルのIDの最大値に1足した値で登録したい。

###発生している問題・エラーメッセージ
特定のデータが既に存在しているかチェックし、
その値がない場合だけテーブルを更新したいと思います。
その時、更新するのにIDの値をチェックして自動で入力したいと思います。
SERIAL型を使えば解決する気もするのですが、
もしSERIAL型を使わなくても良い方法があればご教授ください。

###該当のソースコード
以下のサイトを参考にソースコードを作りました。
サイトではUPDATEまで言及していましたが、
UPDATEに関しては今回は必要ありません。

http://skworkspace.net/archives/170

Table f id | value 1 | 100 2 | 51 3 | 23 ・ ・ ・

例えば、30という数値がテーブルに保存されていない場合登録したいとします。
上記のサイトを参考に以下のSQL文を最初に考えましたが、fを参照できていないのでエラーがでます。

INSERT INTO f (id, value) SELECT max(id + 1), 30 WHERE NOT EXISTS (SELECT 1 FROM f WHERE value=30);

そこで以下のようにfを参照するようにしました。

INSERT INTO f (id, value) SELECT max(id + 1), 30 FROM f WHERE NOT EXISTS (SELECT 1 FROM f WHERE value=30);

すると無事にINSERTされるようになりましたが、
本来はvalueが30のデータがある場合はINSERTしてほしくないのに、INSERTされてしまいます。
しかもidの値はない状態でINSERTされています。

Table f id | value 1 | 100 2 | 51 3 | 23 4 | 30 | 30

どうやらmax(id + 1)を加えたことが原因のようです。
SERIAL型にする以外の解決法があれば教えて下さい。
よろしくお願いします。

###補足情報(言語/FW/ツール等のバージョンなど)
PostgreSQL version 9.5.4

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2016/09/12 07:25

グループ関数の特性を全く理解してないきがする。
acre_maker

2016/09/12 08:04

勉強不足でした。ご指摘ありがとうございます。
guest

回答1

0

ベストアンサー

2番目のSQLのSELECT max(id + 1),部を
select (select max(id) from f ) + 1 ,に置き換えてください

素直にシーケンスなり使った方がいいと思います。

投稿2016/09/12 07:37

omochi

総合スコア410

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

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

acre_maker

2016/09/12 08:04

サブクエリをもう一個持ってくるんですね。いわれてみたらふつうのコトですがご指摘受けるまで気づきませんでした。 ありがとうございました!
omochi

2016/09/12 08:10

末尾にlimit 1も追加してください
acre_maker

2016/09/13 01:18

追記ありがとうございます。おっしゃるとおり最初LIMIT 1が必要でしたが、 INSERT INTO f (id, value) SELECT (SELECT max(id + 1) FROM f), 30 WHERE NOT EXISTS (SELECT 1 FROM f WHERE value=30); にしたらLIMIT 1も必要なくなりました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問