Найти дубликаты для нескольких столбцов эксклюзивной ID-колонки - PullRequest
4 голосов
/ 18 февраля 2011

Я нашел много ответов о том, как найти дубликаты, включая 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.

Так что мне нужно следовать тому, что не работает, потому что идентификатор должен быть агрегирован:

SELECT ID
 from T1
 GROUP BY C1, C2, C3
 HAVING COUNT(*) <> 1

(ID всех дубликатов должен быть разным, но столбцы должны быть равными)

Редактировать :

Спасибо всем.Я всегда удивляюсь, как быстро люди дают отличные ответы на Stackoverflow!

Ответы [ 6 ]

6 голосов
/ 18 февраля 2011

Здесь предлагается множество версий, но я думаю, что придумал новую.

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)
3 голосов
/ 18 февраля 2011

Чтобы получить все строки, которые являются дубликатами:

Используйте это:

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 
3 голосов
/ 18 февраля 2011
;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  
1 голос
/ 18 февраля 2011

Предполагается, что для 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
0 голосов
/ 18 февраля 2011

Вы можете сохранить комбинацию C1, C2, C3 для дубликатов во временной таблице и затем присоединиться к ней, чтобы получить идентификаторы.

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
0 голосов
/ 18 февраля 2011

Я не совсем понимаю вашу проблему, но вот пример другого стиля решения:

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
...