我在postgres上有这样的行:
name | address | college
john | rome |
john | rome |
max | tokyo |
我创建了一个这样的表:
create test (
name varchar(10),
address varchar(20),
college varchar(20),
constraint test_uq unique (name,address,college);
如何使空值变为唯一,因此输出可以是这样的:
name | address | college
john | rome |
max | tokyo |
答案 0 :(得分:2)
Postgres文档claims此行为符合SQL标准:
通常,当存在两个或更多时,违反了唯一约束 表中包含所有列的值的行 约束是平等的。但是,不考虑两个空值 在这个比较中相等。这意味着即使存在独特的 约束可以存储包含null的重复行 至少一个受约束列中的值。这种行为 符合SQL标准[。]
一种可能性是重新考虑您的架构(说实话,name+address+college
上的唯一性约束在您的示例中并没有完全有意义。)
答案 1 :(得分:2)
如果您只需要查询结果中的唯一记录,请使用SELECT DISTINCT
postgres=# SELECT * FROM test; name | address | college ------+---------+--------- john | rome | john | rome | max | tokyo | (3 rows) postgres=# SELECT DISTINCT * FROM test; name | address | college ------+---------+--------- john | rome | max | tokyo | (2 rows)
如果要强制忽略空值的唯一记录,则必须创建conditional unique index
postgres=# CREATE UNIQUE INDEX test_index ON test (name, address) WHERE college IS NULL; CREATE INDEX postgres=# INSERT INTO test (name, address) VALUES ('john', 'rome'); INSERT 0 1 postgres=# INSERT INTO test (name, address) VALUES ('max', 'tokyo'); INSERT 0 1 postgres=# INSERT INTO test (name, address, college) VALUES ('john', 'rome', 'college'); INSERT 0 1 postgres=# INSERT INTO test (name, address) VALUES ('john', 'rome'); ERROR: duplicate key value violates unique constraint "test_index" DETAIL: Key (name, address)=(john, rome) already exists.
HTH
答案 2 :(得分:0)
如果你把它作为主键,而不是一个唯一的约束,那就可以了。为此,列college
必须是NOT NULL
并使用(例如)空字符串而不是NULL值。
或者您正在寻找查询?
答案 3 :(得分:0)
NULL未知,因此NULL值等于NULL永远不会为真。要解决这个问题,请这样做。
为您的大学创建一个新的查找表。在该表中有一个值为None的记录。然后将一个外键放入新的大学查询表。
这是伪代码,所以你可能不得不弄乱它以使它工作,但这是基本的想法。
CREATE TABLE college(college_id SERIAL PRIMARY KEY,college_type);
INSERT INTO college(college_type)
SELECT 1,None;
create test (
name varchar(10),
address varchar(20),
college_id INTEGER NOT NULL DEFAULT 1,
constraint test_uq unique (name,address,college_id);