teratail header banner
teratail header banner
質問するログイン新規登録

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

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

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

INSERTとは、行を追加する、コンピュータのデータベース言語SQLにおけるデータ操作言語(DML)ステートメントの1つである

PostgreSQL

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

1回答

1549閲覧

sqlで複数テーブルを比較して、存在しないデータを片方のテーブルにinsert intoしたい。

000mm

総合スコア6

INSERT

INSERTとは、行を追加する、コンピュータのデータベース言語SQLにおけるデータ操作言語(DML)ステートメントの1つである

PostgreSQL

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2022/06/13 09:57

編集2022/06/13 09:59

0

0

前提

Postgres12

実現したいこと

・2つのテーブルを比較して、片方のテーブルに存在しないデータは追加し、
存在するデータは更新するようにしたい。

 → testテーブルに、tmp_testテーブルからデータを追加したい。

  → 指定の日以降のデータでtestテーブルに存在しないけどtmp_testテーブルには存在するデータを追加したい

発生している問題・エラーメッセージ

意図したレコードが追加されない

該当のソースコード

sql

1INSERT INTO test 2SELECT 3 id 4 ,name 5 ,time_stamp 6FROM 7 tmp_test 8WHERE NOT EXISTS 9 ( 10 select 11 id 12 ,name 13 ,time_stamp 14 from 15 test 16 where 17 time_stamp >= cast( '2022-06-05' as timestamp) 18 ) 19 ON CONFLICT ON CONSTRAINT test_pkey 20 DO UPDATE SET 21 name = excluded.name 22 ,time_stamp = excluded.time_stamp 23;

それぞれのテーブル内容

primary key はtestテーブル側のみ idで指定しています

[testテーブル] id | name | ts ----+------+--------------------- 1 | A | 2022-06-03 01:00:00 2 | B | 2022-06-04 01:00:00 3 | C | 2022-06-04 11:00:00 4 | D | 2022-06-05 20:00:00 5 | Z | 2022-06-03 01:00:00 9 | F | 2022-06-02 01:00:00
[tmp_testテーブル] id | name | ts ----+------+--------------------- 2 | Y | 2022-06-04 23:00:00 5 | Z | 2022-06-03 01:00:00 6 | X | 2022-06-05 01:00:00 9 | F | 2022-06-02 01:00:00

追加されてほしいデータ

上記のsql, テーブルの場合、
2022-06-05 以降のデータでtestテーブルには存在しない
id = 6, name = X, ts = 2022-06-05 01:00:00 の
データのみがtestテーブルに追加されてほしいです。

実際には上記を実行してもレコードは追加されず、
INSERT 0 0で終了してしまいます。

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

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

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

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

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

guest

回答1

0

ベストアンサー

  1. tmp_testテーブルからtime_stampが2022/06/05以降のデータを取得
  2. 1.で取得できたデータのうち、同じidのデータがtestテーブルあればUPDATE、なければINSERT

やりたいことはこれであっていますか? あっているのであれば、以下のようなSQLで実現可能かと思います。

SQL

1INSERT INTO test (id, name, time_stamp) 2SELECT id, name, time_stamp 3FROM tmp_test 4WHERE time_stamp >= timestamp '2022-06-05' 5ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name, time_stamp = EXCLUDED.time_stamp;

投稿2022/06/13 15:02

neko_the_shadow

総合スコア2395

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

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

000mm

2022/06/14 00:58

回答ありがとうございます! やりたいことは、明記していただいたことで半分合っているのですが、 「1. tmp_testテーブルからtime_stampが2022/06/05以降のデータを取得」のところで、 「1. tmp_testテーブルからtime_stampがyyyy/mm/dd以降のデータを取得、ただしtestテーブルのyyyy/mm/dd以降のデータの中にtmp_testから取得するデータが既に含まれている場合は取得しない」としたいと考えています。 例えば指定するtime_stampを2022/06/03とした場合、 tmp_testテーブルではid = 2,5,6が対象になりますが、 testテーブルの2022/06/03以降のデータの中に id:5 のデータは既に存在しているため取得対象とはしたくなく、 testテーブルには含まれないid = 6と、 testテーブルにidは含まれているもののその他の値が異なる id = 2のみを取得対象とし、 その後 「2. 1.で取得できたデータのうち、同じidのデータがtestテーブルあればUPDATE、なければINSERT」という形で動いてほしいのですが可能でしょうか…?
neko_the_shadow

2022/06/14 02:57

やりたいことが追記していただいた通りであれば、現状提示しているSQLでも想定通り稼働するかと思います。 問題となっているid:5ですが、提示しているSQLでは、tmp_testの値でUPDATEしようとします。 ただ、testテーブルのid:5の値とtmp_testテーブルのid:5の値が同じなのであれば、tmp_testの値でUPDATEしても問題ないかと思います。
000mm

2022/06/15 01:23

続いてご回答いただき誠にありがとうございます…!! ご提示いただいたsqlで対応しようと思います! もし良ければなのですが、私自身が書いたSQLでレコードが1つも取得できない理由というのがいくら考えても思い付かず…、問題点が理解できていないままですので、もし可能であれば私のSQLはなぜ誤りなのかというのをご指摘いただけると嬉しいです…!
neko_the_shadow

2022/06/15 14:26

EXISTS句のサブクエリが、tmp_testとのつながりをもっていない、必ず結果を返すクエリになってしまっているのが問題だと思われます。
000mm

2022/06/16 01:11

ありがとうございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問