避免在postgreSQL中重复

时间:2018-04-02 08:16:44

标签: sql postgresql

我使用的是postgreSQL版本10.3,我有一个这样的表:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "project": {
    "name": "project-name"
  },
  "apps": [
    {// app property values here}

  ],
  "e2e": {
    "protractor": {
      "config": "./protractor.conf.js"
    }
  },
  "test": {
    "karma": {
      "config": "./karma.conf.js"
    }
  },
  "defaults": {
    "styleExt": "scss",
    "component": {},
    "serve": {
      "port": 3000
    },
    "build": {
      "deleteOutputPath": false
    }
  }
}

我想制作大量CREATE TABLE IF NOT EXISTS example ( id SERIAL PRIMARY KEY, first VARCHAR(64) NOT NULL, second VARCHAR(255) NOT NULL, third VARCHAR (255), fourth VARCHAR (4) NOT NULL, fifth VARCHAR(12) NOT NULL); 并确保没有重复项。 所以我考虑过使用INSERT

只有当表INSERT INTO ... ON CONFLICT DO NOTHING;中的值不存在时,才会插入记录。 问题是first | second | third | fourth | fifth会自动递增,因此每条记录都不同,因此始终会发生id

我们在这里看到我的意思:

INSERT

记录db=# CREATE TABLE IF NOT EXISTS example (id SERIAL PRIMARY KEY, first VARCHAR(64) NOT NULL, second VARCHAR(255) NOT NULL, third VARCHAR (255), fourth VARCHAR (4) NOT NULL, fifth VARCHAR(12) NOT NULL); CREATE TABLE db=# \dt Lista delle relazioni Schema | Nome | Tipo | Proprietario --------+---------+---------+-------------- public | example | tabella | admin (1 riga) db=# INSERT INTO example (first, second, third, fourth, fifth) VALUES ('1', '2', '3', '4', '5') ON CONFLICT DO NOTHING; INSERT 0 1 db=# SELECT * FROM example; id | first | second | third | fourth | fifth ----+-------+--------+-------+--------+------- 1 | 1 | 2 | 3 | 4 | 5 (1 riga) db=# INSERT INTO example (first, second, third, fourth, fifth) VALUES ('11', '22', '33', '44', '55') ON CONFLICT DO NOTHING; INSERT 0 1 db=# SELECT * FROM example; id | first | second | third | fourth | fifth ----+-------+--------+-------+--------+------- 1 | 1 | 2 | 3 | 4 | 5 2 | 11 | 22 | 33 | 44 | 55 (2 righe) db=# INSERT INTO example (first, second, third, fourth, fifth) VALUES ('111', '222', '333', '444', '555') ON CONFLICT DO NOTHING; INSERT 0 1 db=# SELECT * FROM example; id | first | second | third | fourth | fifth ----+-------+--------+-------+--------+------- 1 | 1 | 2 | 3 | 4 | 5 2 | 11 | 22 | 33 | 44 | 55 3 | 111 | 222 | 333 | 444 | 555 (3 righe) db=# INSERT INTO example (first, second, third, fourth, fifth) VALUES ('1', '2', '3', '4', '5') ON CONFLICT DO NOTHING; INSERT 0 1 db=# SELECT * FROM example; id | first | second | third | fourth | fifth ----+-------+--------+-------+--------+------- 1 | 1 | 2 | 3 | 4 | 5 2 | 11 | 22 | 33 | 44 | 55 3 | 111 | 222 | 333 | 444 | 555 4 | 1 | 2 | 3 | 4 | 5 (4 righe) 等于记录(2 | 11 | 22 | 33 | 44 | 55)。它们仅对(4 | 1 | 2 | 3 | 4 | 5)有所不同。 我不希望插入记录id。 我该怎么办?

谢谢

3 个答案:

答案 0 :(得分:3)

使用UNIQUE CONSTRAINT:

ALTER TABLE example ADD CONSTRAINT constraintname UNIQUE (first, second, third, fourth, fifth);

答案 1 :(得分:2)

您可以使用select语句而不是使用多个insert命令,而union将区分值。

insert into example (first, second, third, fourth, fifth)
select '1', '2', '3', '4', '5'
UNION
select '11', '22', '33', '44', '55'
UNION
select '111', '222', '333', '444', '555'
UNION 
select '1', '2', '3', '4', '5';

结果:

 id | first | second | third | fourth | fifth 
----+-------+--------+-------+--------+-------
  5 | 111   | 222    | 333   | 444    | 555
  6 | 1     | 2      | 3     | 4      | 5
  7 | 11    | 22     | 33    | 44     | 55
(3 rows)

答案 2 :(得分:1)

ALTER TABLE example ADD CONSTRAINT constraintname UNIQUE (first, 
second, third, fourth, fifth);
由于可以为空的列,

将无法工作:

third VARCHAR (255)

您可以这样检查:

INSERT INTO example(first, second, third, fourth, fifth) values('1', '2', NULL, '4', '5');
INSERT INTO example(first, second, third, fourth, fifth) values('1', '2', NULL, '4', '5)';

SELECT * FROM example;

输出:

|id|first|second|third|fourth|fifth|
|1|1|2|NULL|4|5|
|2|1|2|NULL|4|5|

你应该:

  1. 设置为非空: ALTER TABLE example ALTER COLUMN third SET NOT NULL;

  2. 具有NULL和NOT NULL条件的两个索引:

    CREATE UNIQUE INDEX ON example(first, second, fourth, fifth) WHERE third IS NULL;
    CREATE UNIQUE INDEX ON example(first, second, third, fourth, fifth) WHERE third IS NOT NULL;
    
  3. 如果COALSCE(third,'')适合您的情况,那么:

    CREATE UNIQUE INDEX ON example (first, second, COALESCE(third, ''), fourth, fifth);