71

ファイルからテーブル PostgreSQL に大量のデータをダンプする必要があります。MySqlで行われているように、「無視」「置換」などをサポートしていないことは知っています。これに関するウェブ上のほとんどすべての投稿は、データを一時テーブルにダンプしてから、「挿入...選択...存在しない場所...」を実行するなど、同じことを提案しました。

これは、ファイル データ自体に重複した主キーが含まれている場合には役に立ちません。PostgreSQL でこれを処理する方法を知っている人はいますか?

PS私はJavaプログラムからこれをやっています。

4

4 に答える 4

94

説明したのと同じアプローチを使用しますが、DELETE(またはグループ化、または変更...)PKメインテーブルにロードする前に一時テーブルに複製します。

何かのようなもの:

CREATE TEMP TABLE tmp_table 
ON COMMIT DROP
AS
SELECT * 
FROM main_table
WITH NO DATA;

COPY tmp_table FROM 'full/file/name/here';

INSERT INTO main_table
SELECT DISTINCT ON (PK_field) *
FROM tmp_table
ORDER BY (some_fields)

詳細: CREATE TABLE ASCOPYDISTINCT ON

于 2012-12-19T09:54:13.437 に答える
55

PostgreSQL 9.5 にはupsert 機能が追加されました。最後のINSERTにON CONFLICT DO NOTHING句が含まれていることを除いて、Igorの指示に従うことができます。

INSERT INTO main_table
SELECT *
FROM tmp_table
ON CONFLICT DO NOTHING
于 2016-09-28T14:39:39.870 に答える
16

イゴールの答えは私を大いに助けてくれましたが、ネイトがコメントで言及した問題にも遭遇しました。次に、おそらくここでの質問に加えて、新しいデータには内部的に重複が含まれているだけでなく、既存のデータとの重複も含まれているという問題がありました。私にとってうまくいったのは次のことでした。

CREATE TEMP TABLE tmp_table AS SELECT * FROM newsletter_subscribers;
COPY tmp_table (name, email) FROM stdin DELIMITER ' ' CSV;
SELECT count(*) FROM tmp_table;  -- Just to be sure
TRUNCATE newsletter_subscribers;
INSERT INTO newsletter_subscribers
    SELECT DISTINCT ON (email) * FROM tmp_table
    ORDER BY email, subscription_status;
SELECT count(*) FROM newsletter_subscribers;  -- Paranoid again

内部複製と外部複製の両方が で同じになりtmp_tableDISTINCT ON (email)パーツによってそれらが削除されます。はORDER BY、目的の行が結果セットの最初に来るようにし、DISTINCTそれ以降のすべての行を破棄します。

于 2014-12-28T16:35:18.163 に答える
0

キーでグループ化された一時テーブルに挿入して、重複を取り除く

存在しない場合は挿入します

于 2012-12-19T07:29:37.420 に答える