2013-05-01 13 views
20

Chciałbym wybrać rekordy z tabeli lub wstawić je do nowej pustej tabeli, w której wiele kolumn jest takich samych, jak inny rekord w bazie danych. Problem jest podobny do tego pytania. Find duplicate records in MySQL Jednak to tylko porównuje jedną kolumnę. Ponadto jedna z moich kolumn, powiedzmy kolumna C w poniższym przykładzie, jest liczbą całkowitą. Podobnie jak pytanie w powyższym linku, chcę, aby każdy z wierszy został zwrócony. Na szczęście nie jestem dostatecznie zaznajomiony z tym, jak łączą się prace, aby samodzielnie to zrozumieć. Wiem, że poniższy kod nie przypomina w rzeczywistości rzeczywistego kodu SQL, jest to najczystszy sposób, w jaki mogę opisać porównania, które próbuję uzyskać.Wybieranie rekordów MySQL dla duplikatów przy użyciu wielu kolumn

SELECT ColumnE, ColumnA, ColumnB, ColumnC from table where (
    Row1.ColumnA = Row2.ColumnA && 
    Row1.ColumnB = Row2.ColumnB && 
    Row1.ColumnC = Row2.ColumnC 
) 

Każda pomoc będzie mile widziane, wszystkie „Wybierz duplikaty z MySQL” pytania widziałem używać tylko jedną kolumnę jako porównanie.

Odpowiedz

46

Jeśli chcesz liczyć duplikaty wśród wielu kolumnach, użyj group by:

select ColumnA, ColumnB, ColumnC, count(*) as NumDuplicates 
from table 
group by ColumnA, ColumnB, ColumnC 

Jeśli chcesz tylko wartości, które są powielane, a liczba jest większa niż 1. Dostajesz to za pomocą klauzuli having:

select ColumnA, ColumnB, ColumnC, count(*) as NumDuplicates 
from table 
group by ColumnA, ColumnB, ColumnC 
having NumDuplicates > 1 

Jeśli rzeczywiście chcesz wszystkie zduplikowane wiersze zwraca, a następnie przystąpić do ostatniego zapytania z powrotem do oryginalnych danych:

select t.* 
from table t join 
    (select ColumnA, ColumnB, ColumnC, count(*) as NumDuplicates 
     from table 
     group by ColumnA, ColumnB, ColumnC 
     having NumDuplicates > 1 
    ) tsum 
    on t.ColumnA = tsum.ColumnA and t.ColumnB = tsum.ColumnB and t.ColumnC = tsum.ColumnC 

To zadziała, zakładając, że żadna z kolumn nie ma wartości NULL. Jeśli tak, to spróbuj:

 on (t.ColumnA = tsum.ColumnA or t.ColumnA is null and tsum.ColumnA is null) and 
     (t.ColumnB = tsum.ColumnB or t.ColumnB is null and tsum.ColumnB is null) and 
     (t.ColumnC = tsum.ColumnC or t.ColumnC is null and tsum.ColumnC is null) 
+3

Excellant odpowiedź, jak zwykle, ale ostatni Przykładem mogą być zapisane w MySQL "null-safe" równa operatora: 'na t.ColumnA <=> tsum.ColumnA i t.ColumnB <=> tsum.ColumnB and t.ColumnC <=> tsum.ColumnC' –

+3

Ta odpowiedź wydaje się działać, ale liczba zwrotów jest dużo inna niż oczekiwałem. Może trzeba kodować niektóre java, które używa pętli, aby to sprawdzić i dać trochę spokoju. Bardzo dziękuję za formatowanie kodu SQL w ten sposób, z nowymi liniami i wcięciami, to naprawdę pomogło mi zrozumieć, co faktycznie zrobił twój kod! – keepitreall89

1

dlaczego nie spróbujesz użyć zrostu lub tworzenia tabeli tymczasowej. ale osobiście, zalecam używanie unii niż tworzenie tymczasowego stołu, bo zajęłoby to dłuższy czas. spróbować zrobić to:.

select field1, field2 from(
    select '' as field2, field1, count(field1) as cnt FROM list GROUP BY field2 HAVING cnt > 1 
    union 
    select ''as field1, field2, cound(field2) as cnt from list group by field1 having cnt > 1 
) 

nadzieję, że to ma sens :)

Powiązane problemy