SQL Server:如何确定一行中多个字段的组合是否唯一?

SQL Server:如何确定一行中多个字段的组合是否唯一?,sql,sql-server,unique,where,composite-key,Sql,Sql Server,Unique,Where,Composite Key,我尝试在T-SQL中执行类似的操作: SELECT ID FROM table WHERE (ID, Firstname, Lastname) IN (SELECT ID, Firstname, Lastname FROM table GROUP BY ID, Firstname, Lastname HAVING (COUNT(ID) > 1) AND (COUNT(Firstname) > 1) AND (COUNT(Lastname) > 1)) 基本上,如果有一行的

我尝试在T-SQL中执行类似的操作:

SELECT ID 
FROM table
WHERE (ID, Firstname, Lastname) IN 
(SELECT ID, Firstname, Lastname
FROM table
GROUP BY ID, Firstname, Lastname
HAVING (COUNT(ID) > 1) AND (COUNT(Firstname) > 1) AND (COUNT(Lastname) > 1))
基本上,如果有一行的ID、Firstname和Lastname的值在另一行中同时重复,我想选择它的ID。我知道having子句的设置方式不是这样的,但请耐心等待。我希望它能像这样工作:

ID Firstname Lastname age
-------------------------
01 Bob       Smith    25
01 Bob       Smith    35
03 Bob       Smith    25
03 Mike      Smith    25
03 Bob       Baloney  25
在上面的示例中,仅选择了“01”,因为它与三列上它下面的字段相匹配03'在任何两列中的ID、firstname或lastname不完全匹配,因此不会被选中。而且,它是否与年龄匹配也没关系,因为我不在乎年龄

如果我添加了这样一个列:

ID Firstname Lastname age
-------------------------
01 Bob       Smith    25
01 Bob       Smith    35
03 Bob       Smith    25
03 Mike      Smith    25
03 Bob       Baloney  25
03 Mike      Smith    32
然后也会选择“03”,因为它现在在三个相关字段上与上面两行的记录匹配

我已经看到了使用派生表来弥补复合WHERE-IN子句支持不足的答案,但我不确定如何将唯一性的概念添加到子查询中


非常感谢

您可以使用
HAVING COUNT(*)>1
查找包含多个条目的所有组合:

SELECT DISTINCT ID 
FROM (SELECT ID,FirstName,LastName
      FROM table1
      GROUP BY ID,FirstName,LastName
      HAVING COUNT(*) > 1
      )sub
演示:

更新:如果你想使用上面的结果来更新表,你可以用很多方法,但是改变识别这些倍数的方式可能更容易,通过使用
COUNT()
OVER()
子句或
ROW\u number()
函数,这取决于你想更新数据的方式,然后,您可以
UPDATE
a
cte

;WITH cte AS (SELECT *, COUNT(*) OVER(PARTITION BY ID,FirstName,LastName) AS CT
                      , ROW_NUMBER() OVER(PARTITION BY ID,FirstName,LastName ORDER BY ID) AS RN
              FROM Table1)
UPDATE cte
SET Somefield = 'SomeValue'
WHERE CT > 1  -- RN > 1
观察两个函数的行为(添加到上面的sql FIDLE链接):


当表中有更多(Address1、Address2,…)列时,情况如何?@SimchaKhabinsky Age是第四列,其他列不会改变行为,如果只需要
ID
值以及某些匹配字段的多个条目,那么这就行了。@GoatCO。我认为子查询足以回答这个问题。现在,如果我想使用这些信息更新同一个表中的字段,update语句中的多个内部联接是否最好?@HarisKhan不需要多个内部联接,您能举个例子说明您想要更新什么吗?
;WITH cte AS (SELECT *, COUNT(*) OVER(PARTITION BY ID,FirstName,LastName) AS CT
                      , ROW_NUMBER() OVER(PARTITION BY ID,FirstName,LastName ORDER BY ID) AS RN
              FROM Table2)
SELECT *
FROM cte