[英]non unique combination of two unique columns
我有列代碼,id和日期和其他一些日期的表。 這些列一起是主鍵。
primary key(id, code, date)
我希望它們在一起是獨一無二的。 但是代碼不能在具有兩個不同ID的表中重復。 例如,這是一種可能的情況:
id code date data
1 123 3/28/2018 "data 1"
1 123 4/28/2018 "data 2"
甚至這個
1 123 3/28/2018 "data 1"
1 124 3/28/2018 "data 2"
雖然不是:
id code date data
1 123 3/28/2018 "data 1"
2 123 4/28/2018 "data 2"
僅當兩行的ID均為1時,才可能有兩行代碼為“ 123”。“ 123”不能與任何其他ID組合。
如何在sql server(版本14)中管理此問題?
您的數據模型錯誤。
您需要一個僅包含id
和code
表(以及除date
之外的任何其他列都可能是相關的。讓我們將此表codes
和id code_id
,因為這就是我的命名方式:
create table codes (
code_id int identity(1, 1) primary key,
code varchar(255) not null unique
);
那里。 現在, code_id
和code
之間的映射是一對一的。 接下來,僅使用code_id
和date
創建一個表:
create table code_dates (
code_date_id int identity(1, 1) primary key,
code_id int,
date date,
contraint fk_code_dates_code_id foreign key (code_id) references codes(code_id)
);
您可以使用code_id
查找code
。 瞧! 您的數據模型是固定的。
Gordon的答案是最好的建議,但是將您的問題視為學術問題,除了您已有的PRIMARY KEY外,您還可以使用CHECK CONSTRAINT來管理所需的內容。
CHECK CONSTRAINT將調用一個以id
和code
為參數的函數。 該函數查詢表,如果沒有其他具有該code
id
,則返回true
否則返回false
。 CONSTRAINT僅允許函數返回true
行。
這可能會做到
create table tmp (id int not null, code int not null, dt datetime not null, data varchar(10)
primary key (id, code, dt));
create function dbo.CheckFunction(@id int, @code int)
returns int
as begin
return (select count(*) from tmp t where t.id <> @id and t.code = @code)
end;
alter table tmp
add constraint chk_CheckFunction
check (dbo.CheckFunction(id, code) = 0);
truncate table tmp;
insert into tmp values
(1 ,123, '3/28/2018', 'data 1')
, (1 ,123, '4/28/2018', 'data 2')
, (1 ,123, '5/28/2018', 'data 2');
select * from tmp;
select count(*) from tmp t where t.id <> 1 and t.code = 123;
insert into tmp values
(2 ,123, '3/28/2018', 'data 1');
select * from tmp;
drop table tmp;
drop function dbo.CheckFunction;
為什么不創建主鍵為id
, code
的Lookup表? 通過對code
施加UNIQUE
約束,您將確保code = 123
只會對id = 1
每對配對。 我們不能在不違反約束的情況下將code = 123
與id = 2
放在一起。
然后在查閱表和您的業務表之間放置一個引用約束。 然后,引用約束將把約束從Lookup表轉移到Business表,該表將堅持認為code = 123
只能匹配id = 1
每個匹配項。
就像是:
DROP TABLE Business;
DROP TABLE Lookup;
CREATE TABLE Lookup
(
id INT NOT NULL,
code INT NOT NULL UNIQUE,
CONSTRAINT PK_Lookup Primary Key (id, code)
);
INSERT INTO Lookup VALUES (1, 123);
INSERT INTO Lookup VALUES (1, 124);
INSERT INTO Lookup VALUES (2, 123); -- Rejected
CREATE TABLE Business
(
id int NOT NULL,
code int NOT NULL,
date date NOT NULL,
data NVARCHAR(20) NOT NULL,
CONSTRAINT PK_Business PRIMARY KEY (id, code, date),
CONSTRAINT FK_Lookup FOREIGN KEY (id, code) REFERENCES Lookup (id, code)
);
INSERT INTO Business VALUES (1, 123, '2018-03-28', 'data 1');
INSERT INTO Business VALUES (1, 123, '2018-04-28', 'data 2');
INSERT INTO Business VALUES (1, 124, '2018-03-28', 'data 2');
INSERT INTO Business VALUES (2, 123, '2018-04-28', 'data 2'); -- Rejected
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.