重複するエントリを削除しながら、PostgreSQL 9.3のテーブルから別のテーブルにデータを挿入しようとしています。
メールアドレスを含む2つのテーブルがあります。
メインテーブルには、メールと各メールアドレスのタグが含まれています。 _(email, tag)
_の組み合わせは一意である必要があり、これにはUnique(email, tag)
の制約があります。
2番目のテーブルは、電子メールアドレスのみを含むテキストファイルからその場で作成されます。そこには多くの重複があります。
上記の制約を破ることなく、一時テーブルからメインテーブルにデータをインポートする必要があります。メールアドレスを含む特定のファイルでは、タグは一定です。
テーブル構造:
_CREATE TABLE emails (
email character varying(128),
tag bigint,
CONSTRAINT "unique-tag-email" UNIQUE (email, tag) )
_
そして
_CREATE TABLE emails_temp (email character varying(128)
_
これが私のクエリです:
_insert into emails(tag,email)
select
655,t.email
from
emails_temp as t
where
not exists ( select email from emails where email = t.email )
_
注:655は、メールアドレスの特定のグループのタグにすぎません。
これは私が得るエラーです:
エラー:重複するキー値が一意の制約「unique-tag-email」に違反していますSQL状態:23505詳細:キー(email、tag)=([email protected]、655)はすでに存在します。
実際、ファイルには2つのメールアドレス[email protected]があります。
言うまでもなく、このエラーのため、メインテーブル(電子メール)には何も追加されていません。
何が悪いのですか?
3可能な種類の重複があります:
一括挿入の行内で重複します。
挿入された行と既存の行の間で複製します。
挿入された行と、他のトランザクションから同時に挿入/更新された行の間で重複します。
私がこの密接に関連した答えで説明したように:
しかし、2。と3.Postgres 9.5からUPSERT(INSERT .. ON CONFLICT DO NOTHING
)。
INSERT INTO emails(tag,email)
SELECT DISTINCT 655, email
FROM emails_temp
ON CONFLICT (email) DO NOTHING;
指定したように、重複がソースの重複エントリ(1。)にのみ起因する場合、必要なのはDISTINCT
だけです。 Postgresのどのバージョンでも機能します。
INSERT INTO emails(tag,email)
SELECT DISTINCT 655, email
FROM emails_temp;