检查 postgres 表中列的唯一性

Hug*_*ley 7 sql postgresql psycopg2

我需要确保表中的列中的值作为较大流程的一部分是唯一的。

我知道这个UNIQUE限制,但我想知道是否有更好的方法来进行检查。

我正在使用以下方式运行查询psycopg2,因此添加该标签,以防万一其中有可以帮助解决此问题的内容。

如果该列是唯一的,我可以添加一个约束。如果列不唯一,添加约束将返回错误。

如果已经存在同名的约束,则会返回有用的错误。在这种情况下,宁愿只检查现有的约束。

如果该列是主键,则可以添加唯一约束而不会出现错误,但在这种情况下,最好仅根据主键认识到该列必须是唯一的。

下面的代码示例。

DROP TABLE IF EXISTS unique_test;
CREATE TABLE unique_test (
pkey INT PRIMARY KEY,
unique_yes CHAR(1),
unique_no CHAR(1)
);

INSERT INTO unique_test (pkey, unique_yes, unique_no)
VALUES(1, 'a', 'a'),
        (2, 'b', 'a');
    
CREATE UNIQUE INDEX CONCURRENTLY u_test_1  ON unique_test (unique_yes);

ALTER TABLE unique_test
ADD CONSTRAINT unique_target_1
UNIQUE USING INDEX u_test_1;

-- the above runs no problem

-- check what happens when column is not unique

CREATE UNIQUE INDEX CONCURRENTLY u_test_2  ON unique_test (unique_no);

ALTER TABLE unique_test
ADD CONSTRAINT unique_target_2
UNIQUE USING INDEX u_test_2;

-- returns:
-- SQL Error [23505]: ERROR: could not create unique index "u_test_2"
--  Detail: Key (unique_no)=(a) is duplicated.


CREATE UNIQUE INDEX CONCURRENTLY u_test_1  ON unique_test (unique_yes);

ALTER TABLE unique_test
ADD CONSTRAINT unique_target_1
UNIQUE USING INDEX u_test_1;

-- returns
-- SQL Error [42P07]: ERROR: relation "unique_target_1" already exists


-- test what happens if adding constrint to primary key column

CREATE UNIQUE INDEX CONCURRENTLY u_test_pkey  ON unique_test (pkey);

ALTER TABLE unique_test
ADD CONSTRAINT unique_target_pkey
UNIQUE USING INDEX u_test_pkey;

-- this runs no problem but is inefficient.
Run Code Online (Sandbox Code Playgroud)

Mik*_*nek 12

如果您只想验证值是否唯一,请使用查询:

select unique_no, count(*)
  from unique_test
 group by unique_no
having count(*) > 1;
Run Code Online (Sandbox Code Playgroud)

如果需要输出boolean

select not exists (
  select unique_no, count(*)
    from unique_test
   group by unique_no
  having count(*) > 1
);
Run Code Online (Sandbox Code Playgroud)


Gor*_*off 6

如果你只想要一个标志,你可以使用:

select count(*) <> count(distinct uniq_no) as duplicate_flag
from unique_test;
Run Code Online (Sandbox Code Playgroud)