Postgres。插入不存在的多行

Postgres. Insert multiple rows which don`t exist

我有像 (<first_value>, <second_value>) 这样的对,我有 table 具有以下结构:

_____________________________________
| id | first_column | second_column |
 

我需要插入所有不存在的对。 我想我需要像 INSERT IF NOT EXIST 这样的东西,但对于每一对。

我尝试使用此代码:

INSERT INTO <table_name>(<first_column>, <second_column>) 
VALUES (CASE 
            WHEN NOT EXISTS (
                SELECT 1 
                FROM <table_name>
                WHERE <first_column> = <pair_1_value_1> AND <second_column> = <pair_1_value_2>
            ) THEN (<pair_1_value_1>, <pair_1_value_2>) 
    
            WHEN NOT EXISTS (
                SELECT 1 
                FROM <table_name>
                WHERE <first_column> = <pair_2_value_1> AND <second_column> = <pair_2_value_2>
            ) THEN (<pair_2_value_1>, <pair_2_value_2>) 

            .....

         END
);

但我收到此错误:INSERT has more target columns than expressions。另外,我认为它不会工作,因为它只会插入首先通过条件的一行。作为其他编程语言中的 if - elif - else 运算符

如果两个 您的条件都不成立,您的查询会尝试将零值插入两列。那是不合适的。在这种情况下,您需要插入零 和两列。

SQL中没有IF;不要试图模仿它。有 WHERE :


CREATE TABLE omg
        ( first_column text
        , second_column text
        , PRIMARY KEY (first_column, second_column)
        );

WITH wtf (one,two) AS (
        VALUES ( 'aa', 'ab')
             , ( 'ba', 'bb')
        )
INSERT INTO omg(first_column, second_column)
SELECT one, two
FROM wtf w
WHERE NOT EXISTS (
        SELECT*
        FROM omg nx
        WHERE nx.first_column = w.one
        AND nx.second_column = w.two
        )
        ;

在您的实际代码中,最好是:

  • 创建一个临时文件 table (CREATE TEMP TABLE wtf as SELECT * FROM omg where 0=1)
  • 所有 值(来自您的 Python 代码)插入此临时 table
  • select (distinct) 来自这个温度 table(而不是来自 wtf CTE)

MERGE 语句不正是您需要的吗? 这个例子似乎像你描述的那样工作,至少对我来说是这样:

CREATE TABLE tgt (a,b) AS (
            SELECT 'A','A'
  UNION ALL SELECT 'B','B'
  UNION ALL SELECT 'C','C'
  UNION ALL SELECT 'D','D'
  UNION ALL SELECT 'E','E'
  UNION ALL SELECT 'F','F'
  UNION ALL SELECT 'G','G'
  UNION ALL SELECT 'H','H'
  UNION ALL SELECT 'I','I'
  UNION ALL SELECT 'J','J'
)
;
-- out CREATE TABLE
MERGE INTO tgt
USING (
  SELECT 'A','A' UNION ALL
  SELECT 'K','K' UNION ALL
  SELECT 'L','L'
) src(a,b)
  ON src.a=tgt.a
 AND src.b=tgt.b
WHEN NOT MATCHED THEN
  INSERT VALUES (src.a,src.b)
;
-- out  OUTPUT 
-- out --------
-- out       2
SELECT * FROM tgt;
-- out  a | b 
-- out ---+---
-- out  A | A
-- out  B | B
-- out  C | C
-- out  D | D
-- out  E | E
-- out  F | F
-- out  G | G
-- out  H | H
-- out  I | I
-- out  J | J
-- out  K | K
-- out  L | L