SQL Server에서 중복 값을 어떻게 찾을 수 있습니까?
이 기사에서는 SQL을 사용하여 테이블 또는 뷰에서 중복 값을 찾는 방법을 알아 봅니다. 프로세스를 단계별로 진행하겠습니다. 간단한 문제로 시작하여 최종 결과를 얻을 때까지 천천히 SQL을 작성합니다.
결국 중복 값을 식별하는 데 사용되는 패턴을 이해하고에서 사용할 수 있습니다.
이 강의의 모든 예는 Microsoft SQL Server Management Studio 및 AdventureWorks2012 데이터베이스를 기반으로합니다. SQL Server 시작하기 가이드를 사용하여 이러한 무료 도구를 사용할 수 있습니다.
SQL Server에서 중복 값 찾기
시작하겠습니다. 이 기사는 실제 요청을 기반으로합니다. 인사 관리자는 같은 생일을 공유하는 모든 직원을 찾기를 원합니다. 그녀는 목록을 BirthDate 및 EmployeeName별로 정렬하기를 원합니다.
데이터베이스를 보면 HumanResources.Employee 테이블이 직원의 생년월일이 포함되어 있으므로 사용할 테이블임을 알 수 있습니다.
At 언뜻보기에 SQL 서버에서 중복 값을 찾는 것이 매우 쉬운 것처럼 보입니다. 결국 데이터를 쉽게 정렬 할 수 있습니다.
하지만 데이터가 정렬되면 더 어려워집니다! SQL은 집합 기반 언어이므로 커서를 사용하는 것 외에는 이전 레코드의 값을 알 수있는 쉬운 방법이 없습니다.
이것을 알고 있다면 값을 비교할 수 있고 동일한 플래그를 레코드를 중복으로 표시합니다.
다행히도이를 수행 할 수있는 다른 방법이 있습니다. INNER JOIN을 사용하여 직원 생일을 맞 춥니 다. 이렇게하면 동일한 생년월일을 공유하는 직원 목록을 얻을 수 있습니다.
이 문서는 계속해서 작성됩니다. 간단한 쿼리로 시작하여 결과를 표시하고 수정이 필요한 항목을 지적하고 계속 진행하겠습니다. 직원 및 생년월일 목록을 가져 오는 것으로 시작합니다.
1 단계 – 생년월일로 정렬 된 직원 목록 받기
특히 미지의 영역에서 SQL로 작업 할 때, 문제 해결이 필요한 경우에만 “최종”SQL을 작성하는 것보다 결과를 확인하면서 작은 단계로 성명을 작성하는 것이 더 낫다고 생각합니다.
힌트 : If 매우 큰 데이터베이스로 작업하는 경우 개발 또는 테스트 버전으로 더 작은 복사본을 만들고이를 사용하여 쿼리를 작성하는 것이 합리적 일 수 있습니다. 이렇게하면 프로덕션 데이터베이스의 성능이 저하되지 않고 모든 사람이 다운되지 않습니다.
첫 번째 단계에서는 모든 직원을 나열합니다.이를 위해 직원 이름을 가져올 수 있도록 Employee 테이블을 Person 테이블에 조인합니다.
지금까지의 쿼리입니다.
SELECT E1.BusinessEntityID, P.FirstName + " " + p.LastName AS FullName, E1.BirthDateFROM HumanResources.Employee AS E1 INNER JOIN Person.Person AS P ON P.BusinessEntityID = E1.BusinessEntityIDORDER BY E1.BirthDate, FullName
결과를 보면 HR 관리자 요청의 모든 요소가 있습니다. 우리는 모든 직원을 표시하고 있습니다
다음 단계에서는 중복 된 값을 찾기 위해 생년월일을 비교할 수 있도록 결과를 설정합니다.
2 단계 – 중복 된 항목을 식별하기 위해 생년월일을 비교합니다.
지금은 이제 동일한 생년월일을 가진 직원을 식별 할 수 있도록 생년월일을 비교하는 수단이 필요한 직원 목록이 있습니다. 일반적으로 중복 값입니다.
비교를 위해 직원 테이블에서 자체 조인을 수행합니다. 셀프 조인은 INNER JOIN의 단순화 된 버전입니다. BirthDate를 조인 조건으로 사용하기 시작합니다. 이렇게하면 생년월일이 같은 직원 만 검색됩니다.
SELECT E1.BusinessEntityID, E2.BusinessEntityID, P.FirstName + " " + p.LastName AS FullName, E1.BirthDateFROM HumanResources.Employee AS E1 INNER JOIN Person.Person AS P ON P.BusinessEntityID = E1.BusinessEntityID INNER JOIN HumanResources.Employee AS E2 ON E2.BirthDate = E1.BirthDateORDER BY E1.BirthDate, FullName
E2.BusinessEntityID를 쿼리에 추가하여 둘 모두의 기본 키를 비교할 수 있습니다. E1 및 E2. 많은 경우에 동일하다는 것을 알 수 있습니다.
BusinessEntityID에 중점을 두는 이유는 이것이 테이블의 기본 키이자 고유 식별자이기 때문입니다. 행의 결과를 식별하고 소스를 이해하는 매우 간결하고 편리한 수단이됩니다.
최종 결과를 얻는 데 점점 가까워지고 있지만 결과를 확인한 후에는 확인할 수 있습니다. E1과 E2 경기에서 같은 기록을 다시 기록합니다.
빨간색 원으로 표시된 항목을 확인하세요. 이는 결과에서 제거해야하는 오탐입니다. 그것들은 그들 자신과 일치하는 동일한 행들입니다.
좋은 소식은 우리가 단지 중복을 식별하는 것에 정말 가깝다는 것입니다.
나는 100 % 보장 된 중복을 파란색 동그라미로 표시했습니다. BusinessEntityID는 다릅니다. 이는 셀프 조인이 서로 다른 행에서 BirthDate와 일치 함을 나타냅니다. 확실한 중복은 확실합니다.
다음 단계에서는 이러한 오 탐지를 결과에서 제거합니다.
3 단계 – 같은 행에 대한 일치 항목 제거 – 오 탐지 제거
이전 단계에서 모든 오 탐지 일치 항목에 동일한 BusinessEntityID가 있음을 알 수 있습니다. 반면, 실제 중복은 같지 않았습니다.
이것은 우리의 큰 힌트입니다.
중복 만보고 싶다면, 조인에서 일치하는 부분 만 가져와야합니다. BusinessEntityID 값이 동일하지 않습니다.
이를 수행하기 위해
E2.BusinessEntityID <> E1.BusinessEntityID
자체 가입에 결합 조건으로 추가 할 수 있습니다. 추가 된 조건은 빨간색으로 표시했습니다.
SELECT E1.BusinessEntityID, E2.BusinessEntityID, P.FirstName + " " + p.LastName AS FullName, E1.BirthDateFROM HumanResources.Employee AS E1 INNER JOIN Person.Person AS P ON P.BusinessEntityID = E1.BusinessEntityID INNER JOIN HumanResources.Employee AS E2 ON E2.BirthDate = E1.BirthDate AND E2.BusinessEntityID <> E1.BusinessEntityIDORDER BY E1.BirthDate, FullName
이 쿼리가 실행되면 결과에 더 적은 수의 행이 표시되고 나머지 행은 진정한 중복입니다.
비즈니스 요청이므로 요청 된 정보 만 표시되도록 쿼리를 정리하겠습니다.
4 단계 – 최종 수정
하자 쿼리에서 BusinessEntityID 값을 제거하십시오. 문제를 해결하는 데 도움이 될뿐입니다.
최종 쿼리가 여기에 나열됩니다.
SELECT P.FirstName + " " + p.LastName AS FullName, E1.BirthDateFROM HumanResources.Employee AS E1 INNER JOIN Person.Person AS P ON P.BusinessEntityID = E1.BusinessEntityID INNER JOIN HumanResources.Employee AS E2 ON E2.BirthDate = E1.BirthDate AND E2.BusinessEntityID <> E1.BusinessEntityIDORDER BY E1.BirthDate, FullName
그리고 다음과 같은 결과를 제시 할 수 있습니다. HR 관리자!
독자 중 한 명인 Mark는 생년월일이 같은 직원이 세 명이면 최종 결과에 중복이있을 것이라고 지적했습니다. 나는 이것을 확인했고 그것은 사실입니다. 각 중복을 한 번만 표시하는 목록을 반환하려면 DISTINCT 절을 사용할 수 있습니다. 이 쿼리는 모든 경우에 작동합니다.
SELECT DISTINCT P.FirstName + " " + p.LastName AS FullName, E1.BirthDateFROM HumanResources.Employee AS E1 INNER JOIN Person.Person AS P ON P.BusinessEntityID = E1.BusinessEntityID INNER JOIN HumanResources.Employee AS E2 ON E2.BirthDate = E1.BirthDate AND E2.BusinessEntityID <> E1.BusinessEntityIDORDER BY E1.BirthDate, FullName
최종 설명
다음은 테이블에서 중복 데이터를 식별하기 위해 취한 단계입니다. .
- 우리는 먼저보고자하는 데이터에 대한 쿼리를 만들었습니다. 이 예에서 이것은 직원과 생년월일이었습니다.
- 우리는 Geek Speak에서 동일한 테이블에 대해 자체 조인, INNER JOIN을 수행하고 중복 된 것으로 간주되는 필드를 사용했습니다. 우리의 경우 중복 된 생일을 찾고 싶었습니다.
- 마지막으로 기본 키가 동일한 행을 제외하여 동일한 행과 일치하는 항목을 제거했습니다.
단계별 접근 방식을 통해 쿼리를 생성 할 때 많은 추측 작업을 수행했음을 알 수 있습니다.
쿼리 작성 방법을 개선하고 싶거나이 모든 것에 혼란스러워하는 경우 안개를 없애는 방법이 있다면, SQL 개선을위한 3 단계 가이드를 제안하겠습니다.