两个独特列的非唯一组合

时间:2018-03-27 19:59:49

标签: sql sql-server database

我的表格包含代码,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)中管理它?

4 个答案:

答案 0 :(得分:0)

您的数据模型错误。

您需要一个仅包含idcode的表格(除date以外的任何列可能都相关。让我们将此表codes和id {{{}称为1}},因为我就是这样命名的:

code_id

有。现在create table codes ( code_id int identity(1, 1) primary key, code varchar(255) not null unique ); code_id之间的映射是一对一的。接下来,仅使用codecode_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。瞧!您的数据模型已修复。

答案 1 :(得分:0)

戈登的答案是最好的建议,但将你的问题视为学术问题,你可以使用CHECK CONSTRAINT以及你已有的PRIMARY KEY来管理你想要的问题。

CHECK CONSTRAINT会调用一个以x = [1.34, 0.92, 0.68, 0.25, -0.06, -0.34, -0.49, -0.72, -0.79, -0.94, -1.35, -0.35, 0.54, 0.68, 0.84, 1.20, 1.23, 1.32, 1.34]; y = [0.30, 0.43, 0.90, 1.40, 1.13, 1.08, 1.14, 1.23, 0.52, 0.21, -0.20, -0.73, -0.73, -0.82, -0.71, -0.76,-0.46, -0.13, 0.30]; % First derivative dsx = diff(x); dsy = diff(y); ds = sqrt(dsx.^2+dsy.^2); Tx = dsx./ds; Ty = dsy./ds; % Second derivative & curvature ds2 = 0.5*(ds([end,1:end-1])+ds); Hx = diff(Tx([end,1:end]))./ds2; Hy = diff(Ty([end,1:end]))./ds2; % Plot clf hold on plot(x,y,'ro-'); x = x(1:end-1); y = y(1:end-1); % remove repeated point quiver(x+dsx/2,y+dsy/2,Ty,-Tx,'k','autoscalefactor',0.3); quiver(x,y,Hx,Hy,'b','autoscalefactor',1.2); set(gca,'xlim',[-2 2],'ylim',[-1.5 2]); axis equal id为参数的函数。如果没有其他code具有trueid,则该函数会查询该表并返回code。 CONSTRAINT仅允许函数返回false的行。

答案 2 :(得分:0)

这可能会这样做

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;

答案 3 :(得分:0)

为什么不创建主键为idcode的Lookup表?通过在UNIQUE上设置code约束,您将确保code = 123只与id = 1配对。在不违反约束的情况下,我们无法将code = 123置于id = 2

然后在Lookup表和Business表之间放置一个引用约束。然后,引用约束将把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