2015-02-10 19 views
5

Mam poniższą tabelę i teraz muszę usunąć wiersze, które mają duplikat "refIDs", ale mają co najmniej jeden wiersz z tym ref, tj. Muszę usunąć wiersze 4 i 5. proszę mi pomóc w tymusuń duplikaty wierszy na podstawie wartości jednej kolumny

+----+-------+--------+--+ 
| ID | refID | data | | 
+----+-------+--------+--+ 
| 1 | 1023 | aaaaaa | | 
| 2 | 1024 | bbbbbb | | 
| 3 | 1025 | cccccc | | 
| 4 | 1023 | ffffff | | 
| 5 | 1023 | gggggg | | 
| 6 | 1022 | rrrrrr | | 
+----+-------+--------+--+ 
+0

Zastosowanie min() lub max() funkcja – Milkmaid

+0

Patrz następującym pytaniem http : //stackoverflow.com/questions/18932/how-can-i-remove-duplicate-rows –

+0

Czy chcesz zaznaczyć wiersze, ale wykluczyć wiersz 4 i 5, czy naprawdę chcesz je usunąć z tabeli ? – jarlh

Odpowiedz

5

Jest to podobne do zapytania Gordona Linoff, ale bez podkwerendzie:

DELETE t1 FROM table t1 
    JOIN table t2 
    ON t2.refID = t1.refID 
    AND t2.ID < t1.ID 

ta wykorzystuje wewnętrzny łączą się tylko usuwanie wierszy, w których występuje inny rząd z tego samego refID ale niższej ID.

Korzyścią z uniknięcia podzapytania jest możliwość wykorzystania indeksu do wyszukiwania. Ta kwerenda powinna dobrze działać z indeksem wielu kolumn dla identyfikatora + identyfikatora.

1

w MySQL, można to zrobić z join w delete:

delete t 
    from table t left join 
     (select min(id) as id 
      from table t 
      group by refId 
     ) tokeep 
     on t.id = tokeep.id 
    where tokeep.id is null; 

dla każdego RefId, podzapytanie wylicza minimum kolumnie id (domniemywa się być unikalna ponad cal e tabela). Używa on do meczu left join, więc wszystko, co nie pasuje, ma wartość NULL dla tokeep.id. Są to te, które zostały usunięte.

0

to zrobić:

delete from t where 
ID not in (select min(ID) from table t group by refID having count(*) > 1) 
and refID in (select refID from table t group by refID having count(*) > 1) 

kryterium jest refId jest jednym z dwóch powtórzeniach, a identyfikator jest różny od min (Id) z duplikatów. Byłoby lepiej gdyby refId jest indeksowana

inaczej i pod warunkiem, można wydać wiele razy następujące zapytanie dopóki niczego nie usuwać

delete from t 
where 
ID in (select max(ID) from table t group by refID having count(*) > 1) 
Powiązane problemy