Sql 查找多个列的重复项独占ID列
我已经找到了很多关于如何查找重复项的答案,包括PK列或不关注它,如下所示: 如果您有一个名为T1的表,列是c1、c2和c3,那么此查询将显示重复的值Sql 查找多个列的重复项独占ID列,sql,sql-server,sql-server-2005,tsql,duplicates,Sql,Sql Server,Sql Server 2005,Tsql,Duplicates,我已经找到了很多关于如何查找重复项的答案,包括PK列或不关注它,如下所示: 如果您有一个名为T1的表,列是c1、c2和c3,那么此查询将显示重复的值 SELECT C1, C2, C3, count(*)as DupCount from T1 GROUP BY C1, C2, C3 HAVING COUNT(*) > 1 但更常见的要求是获取所有具有相同c1、c2、c3值的副本的ID 因此,我需要以下不起作用的内容,因为必须聚合id: SELECT ID from T1 GRO
SELECT C1, C2, C3, count(*)as DupCount
from T1
GROUP BY C1, C2, C3
HAVING COUNT(*) > 1
但更常见的要求是获取所有具有相同c1、c2、c3值的副本的ID
因此,我需要以下不起作用的内容,因为必须聚合id:
SELECT ID
from T1
GROUP BY C1, C2, C3
HAVING COUNT(*) <> 1
选择ID
从T1开始
按C1、C2、C3分组
有计数(*)1
(所有副本的ID必须不同,但列必须相等)
编辑:
谢谢大家。我总是惊讶于人们在Stackoverflow上给出优秀答案的速度 我不完全理解你的问题,但这里有一个不同风格的解决方案:
;WITH CTE
AS (SELECT ID,
C1,
C2,
C3,
COUNT(*) OVER (PARTITION BY C1, C2, C3) AS Cnt
FROM T1)
SELECT ID,
C1,
C2,
C3
FROM CTE
WHERE Cnt > 1
select id
from t1 a
join t1 b on a.c1 = b.c2
join t1 c on b.c2 = c.c3
where a.id <> b.id and b.id <> c.id and a.id <> c.id
选择id
从t1到a
在a.c1=b.c2上连接t1和b
在b.c2=c.c3上连接t1和c
其中a.id b.id和b.id c.id和a.id c.id
要获取所有重复的行,请执行以下操作:
使用以下命令:
WITH Dups AS
(
SELECT *,
COUNT(1) OVER(PARTITION BY C1, C2, C3) AS CNT
FROM T1
)
SELECT *
FROM Dups
WHERE CNT > 1
要获得唯一行(即保留一行并过滤其他重复行),请使用以下命令:
WITH NoDups AS
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY C1, C2, C3 ORDER BY ID) AS RN
FROM T1
)
SELECT *
FROM NoDups
WHERE RN = 1
假设CTE至少有SQL 2005:
;with cteDuplicates as (
select c1, c2, c3
from t1
group by c1, c2, c3
having count(*) > 1
)
select id
from t1
inner join cteDuplicates d
on t1.c1 = d.c1
and t1.c2 = d.c2
and t1.c3 = d.c3
您可以将重复的C1、C2、C3组合存储到临时表中,然后将其加入以获取ID
select C1, C2, C3
into #duplicates
from T1
group by C1, C2, C3
having count(*) > 1
select ID
from T1 t
inner join #duplicates d
on t.C1 = d.C1
and t.C2 = d.C2
and t.C3 = d.C3
这里有很多建议的版本,但我想我想出了一个新的
select *
from @T as T1
where exists (select *
from @T as T2
where
T1.ID <> T2.ID and
T1.C1 = T2.C1 and
T1.C2 = T2.C2 and
T1.C3 = T2.C3)
选择*
从@T到T1
存在的位置(选择*
从@T到T2
哪里
T1.ID T2.ID和
T1.C1=T2.C1和
T1.C2=T2.C2和
T1.C3=T2.C3)
你能提供一些示例数据吗?这个答案假设sql server>=2005?@Nathan-Yep。现在是2011年,如果OP需要2000兼容的解决方案,他们应该在问题中说明@马丁:当然可以,但我是否错过了问题中的sqlserver,或者可以假设是这样的:非常感谢,只有25秒。45分钟后我取消了第一次进近;)与需要25秒的递归cte相比,您的方法只需要11秒。@Tim-它们不是递归cte。它们是使用窗口聚合函数的CTE@Mikael+1检查是否存在是这里所需要的全部。