Referință - de - sql (LMD), cum să eliminați rândurile duplicate din tabel

De obicei, apare această întrebare atunci când proiectarea tabelelor greșeli, în special, nu există nici o cheie primară, și deja există dovezi care împiedică crearea sa. În acest domeniu constrângerile necesită unicitatea datelor.

Să presupunem că avem următorul tabel T:

Pentru simplitate, eu nu includ aici celelalte coloane, presupunând că datele pe care le sunt determinate în mod unic de valoarea în numele coloanei. Vrei să faci o coloană de nume unic (de exemplu, cheia primară), după eliminarea duplicatelor.

O soluție comună pentru această problemă este de a asigura structura necesară a tabelului auxiliar, care este copiat de rânduri unice în tabela T, urmată de îndepărtarea T tabelă și redenumirea tabelul auxiliar. Mai jos este codul în T-SQL. implementează algoritmul.

Rezultatul este ceea ce ne-am dorit:

În acest caz, constrângerea cheie primară va preveni apariția duplicate după aceea.

Este posibil să se facă fără a crea un tabel nou? Posibil. De exemplu, folosind următorul algoritm:
- adăugați un contor nou tip coloană (IDENTITY), care renumerota toate rândurile din tabel;
- din fiecare grup de rânduri cu aceeași valoare în numele coloanei pentru a șterge toate rândurile, cu excepția rândurilor cu numărul maxim (sau minim - oricum, pentru că avem de-a face cu duplicate);
- îndepărtați coloana auxiliară;
- impune o restricție.

Aici este un exemplu de o astfel de abordare:

Și dacă fără a crea o coloană suplimentară? Din nou, răspunsul este da, dar atunci avem nevoie de noi caracteristici lingvistice specificate în standardul SQL-99 ANSI. Ideea este de a crea nu o coloană permanentă în tabel, care apoi trebuie să fie eliminate, iar virtual (calculat). Această coloană, vom crea cu ajutorul funcțiilor de ferestre. promovat la gradul fiecărui rând în fereastra definită prin egalitatea valorilor în numele coloanei. În cele din urmă, vom șterge toate rândurile cu un grad mai mare de 1.

Să aruncăm o privire mai atentă la construirea unei cereri pentru eliminarea duplicatelor prin această metodă.

1. Linia de numerotare

Nu putem clasifica doar linia pur și simplu pentru că nu sunt pe ce rang. Faptul că aceeași linie va avea același rang. De aceea, le-am enumera mai întâi, ordine după nume coloană.

rezultatul

2. rândurile duplicate de clasament în cadrul grupurilor

Din păcate, este interzisă (MS SQL Server) pentru a utiliza o funcție fereastră în cadrul funcțiilor de fereastra. Ie nu putem scrie:

și, prin urmare, utilizați sub-interogare:

Aici este rezultatul acestei cereri.

3. Scoateți duplicat al mesei virtuale

înregistrările șterge neacceptate de interogare, adică, nu putem folosi această opțiune:

deoarece în declarația DELETE este permisă numai pentru a folosi o tabelă de bază sau de vizualizare. Prin urmare, am putea crea o vizualizare și șterge înregistrări din ea deja. Desigur, în cazul în înregistrările sunt șterse din tabelul de bază pe care să se creeze o imagine. Deci, putem proceda după cum urmează:

„Din nou, pentru a crea ceva“ - s-ar putea spune. Nu neapărat, și să-l dovedească, vom ajuta la expresia de masă comună (CTE), care poate fi numită o reprezentare virtuală. CTE, deși acestea nu sunt stocate în obiectele de date pot fi utilizate pentru a actualiza operatori. Ca rezultat, totul se reduce la o singură solicitare:

Nu uitați să creați o cheie primară. -)

Am primit un link extern la acest articol și a decis să se să protesteze. -)

Asta e fraza: „Nu putem rang doar linia, pur și simplu pentru că nu sunt pe ceea ce rang.“

Desigur, acest lucru este corect, dar putem renunța la clasament (în detrimentul :-) învățare) prin efectuarea „psevdoranzhirovanie“. Faptul că este posibil să se efectueze numerotare independent pentru fiecare grup, în cazul în care propunerea de OVER ROW_NUMBER funcția de a utiliza PARTITION BY construct. Deci, putem face fără funcția RANK, dacă efectuați o partiție după nume

Acest lucru va facilita cererile ulterioare, în special, ultima soluție la problema eliminarea duplicatelor poate fi rescrisă ca: