簡體   English   中英

PostgreSQL插入並忽略多個列

[英]PostgreSQL insert and ignore multiple columns

我新創建了包含4個唯一字段的表: nsnslugpart_nomfg_sku

我正試圖插入此表約。 來自多個表的200萬行,也有重復的行。

所以主要問題是......

在這種情況下如何模擬insert ignore

根據多列選擇不同或您建議什么?

這是我要插入Part表的數據

 SELECT "PartOld".id,
    "PartOld"."PartNo",
    "PartOld"."Manufacturer",
    "PartOld"."Slug",
    "PartOld"."Description",
    "PartOld"."NSN",
    NULL::numeric AS price,
    "PartOld".name,
    NULL::character varying AS mfg_sku
   FROM "PartOld"
UNION
 SELECT part_item.id,
    NULL::character varying AS "PartNo",
    part_item.manufacturer AS "Manufacturer",
    NULL::character varying AS "Slug",
    part_item.details AS "Description",
    part_item.msn AS "NSN",
    NULL::numeric AS price,
    part_item.name,
    part_item.mfg_sku
   FROM part_item_fetched part_item

這是Part表。

DROP TABLE IF EXISTS "electronic_parts"."Part";
CREATE TABLE "electronic_parts"."Part" (
    "id" int4 NOT NULL DEFAULT nextval('"Part_id_seq"'::regclass),
    "part_no" varchar COLLATE "default",
    "manufacturer" varchar COLLATE "default",
    "description" text COLLATE "default",
    "slug" varchar COLLATE "default",
    "nsn" varchar COLLATE "default",
    "price" numeric,
    "name" varchar COLLATE "default",
    "mfg_sku" varchar COLLATE "default"
)
WITH (OIDS=FALSE);
ALTER TABLE "electronic_parts"."Part" OWNER TO "root";

-- ----------------------------
--  Primary key structure for table Part
-- ----------------------------
ALTER TABLE "electronic_parts"."Part" ADD PRIMARY KEY ("id") NOT DEFERRABLE INITIALLY IMMEDIATE;

-- ----------------------------
--  Indexes structure for table Part
-- ----------------------------
CREATE UNIQUE INDEX  "part_u1" ON "electronic_parts"."Part" USING btree(part_no COLLATE "default" "pg_catalog"."text_ops" ASC NULLS LAST);
CREATE UNIQUE INDEX  "part_u2" ON "electronic_parts"."Part" USING btree(nsn COLLATE "default" "pg_catalog"."text_ops" ASC NULLS LAST);
CREATE UNIQUE INDEX  "part_u3" ON "electronic_parts"."Part" USING btree(mfg_sku COLLATE "default" "pg_catalog"."text_ops" ASC NULLS LAST);

采用

INSERT INTO ...
   (SELECT ...)
ON CONFLICT DO NOTHING;

自9.5以來一直可用,請參閱文檔

您可以使用反連接過濾輸入(通常使用NOT EXISTS()LEFT JOIN + IS NULL ):

WITH data AS (
  -- your query here
  SELECT ...
  UNION ALL ...
),
conflicting_ids AS (
  SELECT id      FROM data GROUP BY id      HAVING COUNT(*) > 1
),
conflicting_part_nos AS (
  SELECT part_no FROM data GROUP BY part_no HAVING COUNT(*) > 1
),
conflicting_nsns AS (
  SELECT nsn     FROM data GROUP BY nsn     HAVING COUNT(*) > 1
),
conflicting_mfg_skus AS (
  SELECT mfg_sku FROM data GROUP BY mfg_sku HAVING COUNT(*) > 1
)
INSERT INTO table_name (column_names)
SELECT d.*
FROM   data d
WHERE  NOT EXISTS(SELECT 1 FROM conflicting_ids a      WHERE a.id = d.id)
AND    NOT EXISTS(SELECT 1 FROM conflicting_part_nos a WHERE a.part_no = d.part_no)
AND    NOT EXISTS(SELECT 1 FROM conflicting_nsns a     WHERE a.nsn = d.nsn)
AND    NOT EXISTS(SELECT 1 FROM conflicting_mfg_skus a WHERE a.mfg_sku = d.mfg_sku)
ON CONFLICT DO NOTHING

注意id也是唯一的,因為它是主鍵。 此外,由於沖突的行是單獨檢查的,因此您不需要UNION 您可以使用UNION ALL ,效率稍高。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM