插入时找出表中的重复行

时间:2011-06-23 05:03:34

标签: sql sql-server tsql

我有一张如下表格

ID   Value
----------
1    A
2    B
3    C
3    C
4    A
4    D
5    A
5    C
5    D

我想要一个可以识别的查询或存储过程如果我尝试插入相同类型的值组合,那么已经存在组合。 例如:如果我想插入

6   A
6   D

会告诉我,id 4已经存在相同的组合。 在MSSQL中有可能吗?

很少注释:当我尝试插入新值时,Id将是新的,因此我们无法在表上搜索具有id,值组合的重复行。 我需要一种方法来搜索具有相同id值组合的重复值。

在我尝试插入

时的上述示例中
6   A
6   D

如果在上表中有A和D具有相同ID的值存在任何行,那么它将会在表中搜索并且有一个ID 4所以它应该让我知道当我有重复的条目尝试插入此内容。

5 个答案:

答案 0 :(得分:2)

这将为您提供@T中已经具有@NewValues中提供的值组合的ID。

declare @T table (ID int, Value char(1))
insert into @T values
(1,    'A'),(2,    'B'),(3,    'C'),(3,    'C'),
(4,    'A'),(4,    'D'),(5,    'A'),(5,    'C'),
(5,    'D')

declare @NewValues table(ID int, Value char(1))
insert into @NewValues values (6,    'A'), (6,    'D')

select T.ID
from @T as T
  inner join @NewValues as N
    on T.Value = N.Value
group by T.ID
having count(*) = (select count(*) from @NewValues)

结果:

ID
4
5

如果你只想要完全匹配,意味着不会返回ID = 5,因为它也有一行值为'C',你可以使用它。

select T.ID
from @T as T
  left outer join @NewValues as N
    on T.Value = N.Value
group by T.ID
having count(N.Value) = (select count(*) from @NewValues) and 
       count(*) = (select count(*) from @NewValues)

我看到你的表中有(3,'C')和(3,'C')。如果你想用输入(6,'C')和(6,'C')检测它,你需要这个查询。

select T.ID
from @T as T
  left outer join (select distinct Value
                   from @NewValues) as N
    on T.Value = N.Value
group by T.ID
having count(N.Value) = (select count(*) from @NewValues) and 
       count(*) = (select count(*) from @NewValues)

填写`@NewValues?具有字符串拆分功能的表。

-- Paramenter to SP
declare @ParamID int = 6
declare @ParamValues varchar(100) = 'A,D'

declare @NewValues table(ID int, Value char(1))
insert into @NewValues
select @ParamID, s
from dbo.Split(',', @ParamValues)

答案 1 :(得分:0)

是的,有可能。一种方法是将主键定义为(ID,Value)。每当有人试图插入现有(ID,Value)元组时,这将抛出异常。

答案 2 :(得分:0)

您应该使用MERGE命令,请参阅此处http://pratchev.blogspot.com/2008/03/upsert-and-more-with-merge.html

答案 3 :(得分:0)

在插入之前,查询与该ID组合的所有字母。然后将要插入的字母添加到该列表中,然后检查每个Id是否存在与列表中所有字母有关系的Id。 如果至少有一个,则通知用户。

答案 4 :(得分:0)

概念是通用量化,关系运算符称为division,俗称"the supplier who supplies all parts"

因为您不认为ID = 5代表副本,所以您应该查看exact division(即没有余数),并且在您的情况下,空的分歧可能不是问题。

有用的文章:On Making Relational Division Comprehensible