2012-07-01 4 views
1

특정 필드에 대해 중복 된 레코드에 대한 모든 정보를 검색해야합니다.자세한 중복 된 레코드를 찾는 방법

drop table if exists test; 

create table test (
id int not null auto_increment primary key, 
surname varchar(50), 
firstname varchar(50), 
sex char(1), 
dob date, 
pob varchar(50), 
otherfield1 varchar(50), 
otherfield2 varchar(50) 
) engine = myisam; 


insert into test (surname,firstname,sex,dob,pob,otherfield1,otherfield2) 
values 
('smith','john','M','2000-01-01','rome','xxx','yyy'), 
('black','jack','M','1990-12-30','milan','aaaaa','vvvv'), 
('smith','john','M','2000-01-01','rome','zzz','aaaaa'), 
('white','mike','M','1980-03-01','naples','zzz','other text'), 
('white','mike','M','1980-03-01','naples','zzz','foo bar'), 
('smith','ann','F','1992-03-05','turin','aaaaaaa','other text'); 


select * from test where (surname,firstname,sex,dob,pob) in (
select 
surname,firstname,sex,dob,pob 
from test 
group by surname,firstname,sex,dob,pob 
having count(*) > 1 
) 

을 나는

"id" "surname" "firstname" "sex" "dob"   "pob" "otherfield1" "otherfield2" 
"1" "smith"   "john" "M" "2000-01-01" "rome"  "xxx" "yyy" 
"3" "smith"   "john" "M" "2000-01-01" "rome"  "zzz" "aaaaa" 
"4" "white"   "mike" "M" "1980-03-01" "naples" "zzz" "other text" 
"5" "white"   "mike" "M" "1980-03-01" "naples" "zzz" "foo bar" 

그러나이 방법은 MSSQL 2005에서 작동하지 않는거야 : 내가 MySQL을 사용한다면

나는이 방법으로 해결할 수

create table #test (
id int identity, 
surname varchar(50), 
firstname varchar(50), 
sex char(1), 
dob datetime, 
pob varchar(50), 
otherfield1 varchar(50), 
otherfield2 varchar(50) 
) 

insert into #test (surname,firstname,sex,dob,pob,otherfield1,otherfield2) values ('smith','john','M','2000-01-01','rome','xxx','yyy'); 
insert into #test (surname,firstname,sex,dob,pob,otherfield1,otherfield2) values ('black','jack','M','1990-12-30','milan','aaaaa','vvvv'); 
insert into #test (surname,firstname,sex,dob,pob,otherfield1,otherfield2) values ('smith','john','M','2000-01-01','rome','zzz','aaaaa'); 
insert into #test (surname,firstname,sex,dob,pob,otherfield1,otherfield2) values ('white','mike','M','1980-03-01','naples','zzz','other text'); 
insert into #test (surname,firstname,sex,dob,pob,otherfield1,otherfield2) values ('white','mike','M','1980-03-01','naples','zzz','foo bar'); 
insert into #test (surname,firstname,sex,dob,pob,otherfield1,otherfield2) values ('smith','ann','F','1992-03-05','turin','aaaaaaa','other text'); 

select * from #test where (surname,firstname,sex,dob,pob) in (
select 
surname,firstname,sex,dob,pob 
from #test 
group by surname,firstname,sex,dob,pob 
having count(*) > 1 
) 

미리 감사드립니다.

편집

이것은 내가 찾은 가능한 솔루션입니다 :

select t1.* from #test as t1 
inner join (select 
      surname,firstname,sex,dob,pob 
      from #test 
      group by surname,firstname,sex,dob,pob 
      having count(*) > 1) as t2 
on t1.surname = t2.surname and t1.firstname = t2.firstname and t1.sex = t2.sex and t1.dob = t2.dob and t1.pob = t2.pob 

하지만 난 더 나은 방법이 있는지 알고 싶습니다. 나는이 모든 조건에 동참하고 싶지 않다.

답변

1
SELECT * /*TODO: Just list desired columns*/ 
FROM (SELECT *, 
       Count(*) OVER (PARTITION BY surname,firstname,sex,dob,pob) AS Cnt 
     FROM #test) T 
WHERE Cnt > 1 

- 또는

SELECT * 
FROM #test t1 
WHERE EXISTS (SELECT * 
       FROM #test t2 
       WHERE t1.id <> t2.id 
         AND EXISTS (SELECT t1.surname, 
             t1.firstname, 
             t1.sex, 
             t1.dob, 
             t1.pob 
            INTERSECT 
            SELECT t2.surname, 
             t2.firstname, 
             t2.sex, 
             t2.dob, 
             t2.pob)) 
+0

안녕 마틴과 친절에 감사드립니다. 두 가지 솔루션을 모두 테스트했습니다. 내 테이블에는 1,5 백만 개의 레코드가 있습니다. 첫 번째 쿼리는 14,000 개의 레코드를 찾기 위해 약 10 분이 소요됩니다. 두 번째 쿼리는 나에게 동일한 레코드 세트를 제공하는 데 90 초가 걸립니다. 다시 한번 감사드립니다. :) –

0
select surname,firstname,sex,dob,pob from 
(
select 
surname,firstname,sex,dob,pob, count(*) as NumberOfRecords 
from #test 
group by surname,firstname,sex,dob,pob 
) dupCount 
Where dupCount.NumberOfRecords > 1 

이 2005

+0

의 안녕을 작동합니다. 답장을 보내 주셔서 감사하지만 모든 필드, 이벤트 otherfield1 및 otherfield2 내 간단한 예제에서 검색해야합니다. mysql을 사용하여 얻은 원하는 출력을 살펴 보자. –

관련 문제