Eliminarea rânduri duplicate în SQL cerere de masă

Atunci când există o problemă de optimizare a bazei de date, sau pentru a schimba structura sa, uneori, o sarcină tailwind de organizare a datelor existente. Ei bine, în cazul în care masa este deja în figura prezentată în forma normală, iar întregul sistem este organizat, astfel încât să nu se acumuleze informații inutile duplicat. În cazul în care acest lucru nu este cazul, atunci în finalizarea unui astfel de sistem ar fi de dorit pentru a scăpa de toate datele redundante și de a face cel mai eficient.

În acest articol considerăm problema șterge rânduri duplicate într-un tabel de baze de date. Imediat, observ că vorbim despre necesitatea de a elimina exact liniile duplicat. De exemplu, intrarea în tabelul de comenzi cu câmpurile „cod de comandă“, „codul produsului“, „ID-ul de client“, „data comenzii“ poate varia în doar codul de comandă, încă un client într-o zi se poate comanda același număr de articol timp. Un indicator principal de aici că totul este corect - prezența câmpului cheie.

În cazul în care, cu toate acestea, vom vedea un tabel sporiți repetarea domenii, fără a fi nevoie explicită a fiecărei înregistrări, acest lucru este exact ceea ce trebuie să fie reparat.

Exemplu tabel clar excesive:

country_id (cod de țară)

CITY_NAME (cod zonă)

Acum, să ne uităm mai în detaliu modul în care funcționează acest lucru. Dacă vi se solicită să eliminați, trebuie să specificați o condiție care indică tipul de date pe care doriți să-l ștergeți, și care să plece. Nu avem nevoie pentru a elimina înregistrarea unică. Ie în cazul în care există mai multe intrări identice (același care, în cazul în care acestea au o valoare egală și city_name country_id), atunci trebuie să ia una dintre liniile, amintiți-vă codul și a șterge toate înregistrările cu aceleași valori și city_name country_id, dar alt cod (id).

șir de interogare SQL:

Ștergerea unui. * DE LA MyTable o,

Aceasta indică faptul că eliminarea va fi efectuată tabelul MyTable.

Apoi, selectați interogare generează un tabel de sprijin, în cazul în care noi, înregistrările de grup, astfel încât toate înregistrările sunt unice:

(SELECT
b.country_id, b.city_name, MIN (b.id) la mijlocul
DE LA MyTable b
GROUP BY b.country_id, b.city_name
) c

MIN (b.id) mid - formează o coloană mid (abreviere min id), care sunt realizate id minim în fiecare subgrup.

Rezultatul este un tabel care conține un număr de înregistrare unic și prima linie pentru fiecare grup de intrări duplicat.

Acum avem două mese. O comună, care conține toate înregistrările. Acesta va fi eliminat din liniile suplimentare. Al doilea conține informații despre liniile pe care doriți să le salvați.

Putem crea doar condițiile, care prevede: necesitatea de a elimina toate rândurile în care același câmp și city_name country_id, și ID-ul nu se va potrivi. În acest caz, id-ul selectat o valoare minimă, astfel încât toate înregistrările sunt șterse, care este mai mult decât id-ul selectat în tabelul temporar.

De asemenea, trebuie remarcat faptul că operațiunea de mai sus poate fi realizată în prezența unui tabel de câmp cheie. Dacă ați întâlnit brusc o masă fără un identificator unic, apoi adăugați-l:

ALTER TABLE `mytable` ADD` id` INT (11) NOT AUTO_INCREMENT NULL. ADD PRIMARY KEY ( `id`)

Se execută o astfel de solicitare, obținem coloană suplimentară umplută cu o valoare numerică unică pentru fiecare rând al tabelului.

Efectuam toate acțiunile necesare. După masa de operație de curățare a înregistrărilor dublură este executat, acest câmp poate fi, de asemenea, eliminate.

Un alt material din această secțiune

Vreau să atrag atenția la ultimul punct, în cazul în care tabelul are identificator nu este unic, acesta trebuie adăugat, dar nu neapărat cheia, toate la fel, apoi eliminați, astfel încât „ADD PRIMARY KEY (` id`)“fac - acțiune inutilă

Bună ziua, Aleksandr.
Într-adevăr, nu este necesar. Câmpul cheie este folosit aici pentru a oferi un mod unic identificatori unici. Se înțelege că câmpul incrementală atribut adăuga coduri unice în ordine crescătoare. Dar, așa cum este descris în articol operația efectuată în același timp, a minimiza codul nu este necesar. Sarcina principală aici - executarea corectă a elementelor de curățare, se repetă.
Vă mulțumim pentru comentariu.

Am făcut un pic mai ușor:
DELETE FROM MyTable unde id NU IN (SELECT MIN (id) din grupul MyTable DE b.country_id, b.city_name);

Andrew, după-amiază bună.
Curios Am studiat codul. Am vrut să verifice în practică. Există o greșeală mică (fără atribuirea celui de al doilea tabel, simbolul „b“) - corectat ea și a fugit după cum urmează:

DELETE FROM MyTable unde id NU IN (SELECT MIN (id) DIN MyTable AS b GROUP BY b.country_id, b.city_name);

Cu toate acestea, există o eroare cu referire la setul returnat de date dintr-o interogare imbricate. Dacă ați avea un cod de lucru vă rugăm să specificați. Ar fi interesant de știut cerere opțiune mai bună.

Încercarea de a aplica algoritmul dvs. (min înlocuit max - trebuie sa plec doar ultima intrare). Eu folosesc următorul cod:

DELETE o. *
De la T1 AS-o,
(SELECT b. [AF] b. [BF], max (b. [Cod]) AS maxID
De la T1 AS b
GROUP BY b. [AF] b. [BF]
) AS c
UNDE a. [AF] = c. [AF] și a. [BF] = c. [BF] și a. [Cod]

Din anumite motive, nu a mers a doua jumătate a mesajului.
Deci, mesajul în performanța algoritmului: „Nu s-a putut șterge din tabelele specificate.“ În același timp, dacă înlocuim Ștergere la Select, eșantionate corect. În ceea ce poate fi cauza erorii?

Am încercat codul de la Andrew:
DELETE *
de la T1
Codul UNDE NU IN (
SELECT max (cod)
de la T1
GROUP BY AF, BF);
Totul funcționează perfect. Vă mulțumesc foarte mult! Deci, întrebarea anterioară intră în categoria pur academice. Dar încă mai interesant.