我们仍然在sql server 2005上。
我们正在尝试在患者桌上创建一个独特的索引。 唯一索引将是多列索引(Status,PatientNumber,First,Last,DOB,Gender)。 但是,数据已包含多个重复项。
我们可以有2条记录(Active,0001,John,Doe,1/1/1960,M)和(Active,0001,John,Doe,1/1/1960,M)它们实际上是重复的1必须被停用。 我们还可以有2条记录(Active,0001,John,Doe,1/1/1960,M)和(Active,0001,John,Doe,1/1/1960,M)并且它们不是重复的,所以练习必须找到2个记录中的一个记录的新PatientNumber,以指示恰好具有相同名称,DOB和性别的2个不同患者。
由于存在重复,用户已经停用了重复以保留一条生存记录。 所以我们可以有3条记录(无效,0001,John,Doe,1/1/1960,M)和(无效,0001,John,Doe,1/1/1960,M)和(Active,0001,John,Doe) ,1/1/1960,M)。必须删除一个非活动dup才能创建唯一索引。
该公司不接受修复现有的重复数据。
我们不希望使用函数强制患者唯一性来检查活动行。
我的计划是根据这个考虑来清理数据:如果数据中存在重复的键值,则无法创建唯一索引,UNIQUE约束或PRIMARY KEY约束。
但是我们的dba说在创建一个唯一的索引时会有一个选项可以让你创建那个索引并且不会抱怨现有的重复???毋庸置疑,听到这个选择,企业很高兴。
例如:我打算在2014年4月1日创建唯一索引。我可以在创建索引时使用一些“选项”来告诉sql server不要打扰2014年4月1日之前存在的重复项吗?创建索引后(即2014年4月1日之后)所有重复都将是违规行为。
我很难找到这个选项。任何人都可以提出建议或评论吗?
谢谢!
答案 0 :(得分:1)
如果键列中存在重复值,则无法创建唯一索引或约束。
那就是说,你可以解决它。以下是一种方式,如果你的情况可以接受由你决定;下面的示例有一个保留,我只有SQL Server 2008测试:)
您可以做的是创建一个_dedupe
列并将其包含在索引中。对于现有重复项,您可以在列中设置唯一值,从而使一行具有NULL
值。插入其他值时,请不要设置_dedupe
列,否则将导致重复插入失败。
作为一个例子;
> CREATE TABLE test ( id INT, value INT );
> INSERT INTO test (id, value) VALUES (1,1),(2,1),(3,3);
id value
----------
1 1
2 1
3 3
> ALTER TABLE test ADD _dedupe INT;
-- Update, partition by the value combination that is not unique now but
-- should be later, in this case "value".
> WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY value ORDER BY id)-1 rn FROM test
)
UPDATE cte SET _dedupe = CASE WHEN rn=0 THEN NULL ELSE rn END;
id value _dedupe
--------------------
1 1 NULL
2 1 1
3 3 NULL
> CREATE UNIQUE INDEX uq_value ON test(value, _dedupe);
> INSERT INTO test (id, value) VALUES (4,1) <-- fail, not unique
这种方法的一个缺点是防止重复插入的唯一行是NULL
行,如果删除,则可能最终得到具有现有编号行的新副本。这对您的系统来说可能是也可能不是问题。