sql - 使进一步的列数据唯一的约束
问题描述
我有一张包含一些数据的表格。现在,我想将非唯一列设为唯一。但问题是,我不想删除表中存在的重复数据,但想限制要添加到表中的数据不唯一。
为了实用:我有一个表 tbl 名称,年龄作为列。我在表中的数据如下:
name |age
-----------------------
kaushikC |21
mohan |27
kumar |29
mohan |31
karthik |55
karthik |76
现在我想使名称列唯一而不删除“mohan”和“karthik”的重复条目。
如何编写这样的约束
解决方案
如果您的表中有一个列允许您识别不想更改的记录,例如identity
列或创建日期,您可以在表上创建一个唯一的过滤索引,在它的where
子句中指定它应该只包括表中的其他记录。
假设您有一个identity
名为 的列id
:
id | name |age
-----------------------
1 | kaushikC |21
2 | mohan |27
3 | kumar |29
4 | mohan |31
5 | karthik |55
6 | karthik |76
您可以在此表上创建一个唯一过滤索引,该索引仅对id
大于 6 的行有效:
CREATE UNIQUE INDEX UX_YourTable_Name_WhereIdGraterThanSix
ON YourTable (Name)
WHERE id > 6;
这将使您能够保持表上其他名称的唯一性 - 但是,它不会阻止您为任何现有名称插入一个更多重复项 - 因此您可以将另一个mohan
或另一个插入kumar
到表中(但只有一个)。
如果要排除所有重复项,包括现有行的重复项,最好的选择可能是使用instead of
触发器进行插入和更新:
CREATE TRIGGER tr_YourTable ON YourTable
INSTEAD OF INSERT, UPDATE
AS
BEGIN
-- the statement that fired the trigger is an update statement
IF EXISTS(select 1 FROM deleted)
BEGIN
UPDATE T
SET name = I.Name
FROM YourTable AS T
JOIN Inserted AS I
ON T.Id = I.Id
WHERE NOT EXISTS
( -- make sure the name is unique
SELECT 1
FROM YourTable AS T1
WHERE T1.Name = I.Name
AND NOT EXISTS
( -- unless it is going to be updated
SELECT 1
FROM Deleted AS D
JOIN Inserted AS I
ON D.Id = I.Id
WHERE D.Id = T1.Id
AND T1.Name = D.Name
AND D.Name <> I.Name
)
)
END
ELSE -- the statement that fired the trigger is an insert statement
BEGIN
INSERT INTO YourTable(Name)
SELECT I.Name
FROM Inserted I
WHERE NOT EXISTS
( -- make sure the name is unique
SELECT 1
FROM YourTable AS T1
WHERE T1.Name = I.Name
)
END
END
推荐阅读
- javascript - JS正则表达式匹配相同的字符对
- python-3.x - Python脚本在Google Drive中创建二进制文件而不是文件夹
- html - 为什么“body[attribute="value] element”CSS 选择器不起作用?
- javascript - 获取所有 React 组件的列表
- python - 从服务器下载文件
- javascript - 为什么我们需要在前端表达?
- javascript - 用于在 Google doc 中为当前选择设置字体的 Apps 脚本
- python - 满足多索引条件时如何组合元组中的对象
- python - 使用相应的目录标记我们的灰度图像
- sql - 树 MySQL8 / MariaDB10 中的递归查询