특정 필드에서 중복을 찾으려면 명령문을 선택하십시오.


415

여러 필드에서 중복 항목을 찾는 SQL 문을 도와 줄 수 있습니까?

예를 들어, 의사 코드에서 :

select count(field1,field2,field3) 
from table 
where the combination of field1, field2, field3 occurs multiple times

위의 문장에서 여러 번 발생 하면 첫 번째 레코드를 제외한 모든 레코드 를 선택 하고 싶습니다 .


3
의사 코드가 모호하며 첫 번째 원하지 않는 순서를 정의하지 않습니다. 샘플 데이터를 줄 것을 제안합니다.
Unreason

답변:


840

여러 레코드가있는 필드 목록을 얻으려면 다음을 사용할 수 있습니다.

select field1,field2,field3, count(*)
  from table_name
  group by field1,field2,field3
  having count(*) > 1

행을 삭제하는 방법에 대한 자세한 내용은이 링크를 확인하십시오.

http://support.microsoft.com/kb/139444

편집 : 다른 사용자가 언급했듯이 위의 링크에서 접근 방식을 사용하기 전에 "첫 번째 행"을 정의하는 방법을 결정하는 기준이 있어야합니다. 이를 바탕으로 order by 절과 필요한 경우 하위 쿼리를 사용해야합니다. 샘플 데이터를 게시 할 수 있다면 실제로 도움이 될 것입니다.


42

"첫 번째"를 언급 했으므로 데이터에 대해 일종의 주문이 있다고 가정합니다. 데이터가 일부 필드에 의해 정렬된다고 가정 해 봅시다 ID.

이 SQL은 첫 번째 항목을 제외하고 중복 항목을 가져옵니다. 기본적으로 (a) 동일한 필드와 (b) 더 낮은 ID를 가진 다른 행이있는 모든 행을 선택합니다. 성능은 좋지 않지만 문제를 해결할 수 있습니다.

SELECT A.ID, A.field1, A.field2, A.field3
  FROM myTable A
 WHERE EXISTS (SELECT B.ID
                 FROM myTable B
                WHERE B.field1 = A.field1
                  AND B.field2 = A.field2
                  AND B.field3 = A.field3
                  AND B.ID < A.ID)

17

이것은 내가 좋아하는 SQL Server 2005의 재미있는 솔루션입니다. "첫 번째 레코드를 제외한 모든 레코드"에 대해 "첫 번째"행을 식별하는 데 사용할 수있는 또 하나의 "id"열이 있다고 가정합니다.

SELECT id
    , field1
    , field2
    , field3
FROM
(
    SELECT id
        , field1
        , field2
        , field3
        , RANK() OVER (PARTITION BY field1, field2, field3 ORDER BY id ASC) AS [rank]
    FROM table_name
) a
WHERE [rank] > 1

방금 SQL Server 2008 태그를 발견했습니다. 내 제안이 여전히 유효 하다니 다행입니다.
Nick Vaccaro

1
또한 문제의 테이블에서 삭제해야 할 행을 반환하기 때문에 탁월한 솔루션
Realto619

1
PARTITION BY 필드 목록을 PK 필드 목록으로 생각하면 도움이됩니다.
bkwdesign

6

중복 값을 보려면

with MYCTE  as (
    select row_number() over ( partition by name  order by name) rown, *
    from tmptest  
    ) 
select * from MYCTE where rown <=1

3

SQL Server 2005 이상을 사용하는 경우 (질문의 태그가 SQL Server 2008을 나타내는 경우) 조인을 사용하는 것이 바람직하지 않거나 어떤 이유로 인해 비실용적 일 경우 순위 함수를 사용하여 첫 번째 레코드 이후에 중복 레코드를 반환 할 수 있습니다. 다음 예제는이를 실제로 보여줍니다. 여기서 검사 된 열의 널값과도 작동합니다.

create table Table1 (
 Field1 int,
 Field2 int,
 Field3 int,
 Field4 int 
)

insert  Table1 
values    (1,1,1,1)
        , (1,1,1,2)
        , (1,1,1,3)
        , (2,2,2,1)
        , (3,3,3,1)
        , (3,3,3,2)
        , (null, null, 2, 1)
        , (null, null, 2, 3)

select    *
from     (select      Field1
                    , Field2
                    , Field3
                    , Field4
                    , row_number() over (partition by   Field1
                                                      , Field2
                                                      , Field3
                                         order by       Field4) as occurrence
          from      Table1) x
where     occurrence > 1

이 예를 실행하면 모든 "그룹"에서 첫 번째 레코드가 제외되고 널값을 가진 레코드가 올바르게 처리됩니다.

그룹 내에서 레코드를 주문할 수있는 열이없는 경우 분할 기준 열을 순서별 열로 사용할 수 있습니다.


1
CREATE TABLE #tmp
(
    sizeId Varchar(MAX)
)

INSERT  #tmp 
    VALUES ('44'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46')


SELECT * FROM #tmp
DECLARE @SqlStr VARCHAR(MAX)

SELECT @SqlStr = STUFF((SELECT ',' + sizeId
              FROM #tmp
              ORDER BY sizeId
              FOR XML PATH('')), 1, 1, '') 


SELECT TOP 1 * FROM (
select items, count(*)AS Occurrence
  FROM dbo.Split(@SqlStr,',')
  group by items
  having count(*) > 1
  )K
  ORDER BY K.Occurrence DESC    

0

이 쿼리를 시도하여 각 SELECT 문의 sepratley 수를 계산하십시오.

select field1,count(field1) as field1Count,field2,count(field2) as field2Counts,field3, count(field3) as field3Counts
from table_name
group by field1,field2,field3
having count(*) > 1
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.