L's ușor de a găsi dubluri cu un singur domeniu:
SELECT name, COUNT(email)
FROM users
GROUP BY email
HAVING COUNT(email) > 1
Deci, dacă avem o masă
ID NAME EMAIL
1 John [email protected]
2 Sam [email protected]
3 Tom [email protected]
4 Bob [email protected]
5 Tom [email protected]
Această interogare ne va da John, Sam, Tom, Tom, pentru că toate au același "e-mail".
Cu toate acestea, ceea ce vreau este de a obtine duplicate cu același "e-mail" și "nume".
Asta este, am vrut pentru a obține "Tom", "Tom".
Motivul pentru care am nevoie de acest lucru: am făcut o greșeală, și a permis pentru a introduce duplicate "nume" și "e-mail" valori. Acum am nevoie pentru a elimina/modifica duplicate, deci am nevoie de a găsi i primul.
SELECT
name, email, COUNT(*)
FROM
users
GROUP BY
name, email
HAVING
COUNT(*) > 1
Pur și simplu grup pe ambele coloane.
Notă: cele mai vechi ANSI standard este de a avea toate non-agregate de coloane din GRUP, dar acest lucru s-a schimbat cu ideea de "dependența funcțională":
În baze de date relaționale teorie, o dependență funcțională este o constrângere între două seturi de atribute într-un raport dintr-o bază de date. Cu alte cuvinte, dependența funcțională este o constrângere care descrie relația dintre atribute într-o relație.
Sprijinul nu este consistent:
încercați acest lucru:
declare @YourTable table (id int, name varchar(10), email varchar(50))
INSERT @YourTable VALUES (1,'John','John-email')
INSERT @YourTable VALUES (2,'John','John-email')
INSERT @YourTable VALUES (3,'fred','John-email')
INSERT @YourTable VALUES (4,'fred','fred-email')
INSERT @YourTable VALUES (5,'sam','sam-email')
INSERT @YourTable VALUES (6,'sam','sam-email')
SELECT
name,email, COUNT(*) AS CountOf
FROM @YourTable
GROUP BY name,email
HAVING COUNT(*)>1
IEȘIRE:
name email CountOf
---------- ----------- -----------
John John-email 2
sam sam-email 2
(2 row(s) affected)
dacă doriți ca id-Urile de dups folosi asta:
SELECT
y.id,y.name,y.email
FROM @YourTable y
INNER JOIN (SELECT
name,email, COUNT(*) AS CountOf
FROM @YourTable
GROUP BY name,email
HAVING COUNT(*)>1
) dt ON y.name=dt.name AND y.email=dt.email
IEȘIRE:
id name email
----------- ---------- ------------
1 John John-email
2 John John-email
5 sam sam-email
6 sam sam-email
(4 row(s) affected)
pentru a șterge duplicate încerca:
DELETE d
FROM @YourTable d
INNER JOIN (SELECT
y.id,y.name,y.email,ROW_NUMBER() OVER(PARTITION BY y.name,y.email ORDER BY y.name,y.email,y.id) AS RowRank
FROM @YourTable y
INNER JOIN (SELECT
name,email, COUNT(*) AS CountOf
FROM @YourTable
GROUP BY name,email
HAVING COUNT(*)>1
) dt ON y.name=dt.name AND y.email=dt.email
) dt2 ON d.id=dt2.id
WHERE dt2.RowRank!=1
SELECT * FROM @YourTable
IEȘIRE:
id name email
----------- ---------- --------------
1 John John-email
3 fred John-email
4 fred fred-email
5 sam sam-email
(4 row(s) affected)
Dacă doriți să ștergeți duplicate, aici's-un mod mult mai simplu să faci decât să găsi/impar de rânduri într-o triplă sub-selectați:
SELECT id, name, email
FROM users u, users u2
WHERE u.name = u2.name AND u.email = u2.email AND u.id > u2.id
Și așa a șterge:
DELETE FROM users
WHERE id IN (
SELECT id/*, name, email*/
FROM users u, users u2
WHERE u.name = u2.name AND u.email = u2.email AND u.id > u2.id
)
Mult mai ușor de citit și de înțeles IMHO
Notă: singura problemă este că veți avea pentru a executa cererea, până când nu există rânduri șterse, deoarece ștergeți numai 1 din fiecare duplicat de fiecare dată
incearca codul asta
WITH CTE AS
( SELECT Id, Name, Age, Comments, RN = ROW_NUMBER()OVER(PARTITION BY Name,Age ORDER BY ccn)
FROM ccnmaster )
select * from CTE
Acest selectează/șterge toate înregistrările duplicat, cu excepția o înregistrare din fiecare grup de duplicate. Deci, ștergeți frunzele toate înregistrări unice + o înregistrare din fiecare grup de copii.
Selectați duplicate:
SELECT *
FROM table
WHERE
id NOT IN (
SELECT MIN(id)
FROM table
GROUP BY column1, column2
);
Șterge duplicate:
DELETE FROM table
WHERE
id NOT IN (
SELECT MIN(id)
FROM table
GROUP BY column1, column2
);
Fiți conștienți de cantități mai mari de înregistrări, aceasta poate provoca probleme de performanță.
În cazul în care lucrați cu Oracle, în acest fel, ar fi de preferat:
create table my_users(id number, name varchar2(100), email varchar2(100));
insert into my_users values (1, 'John', '[email protected]');
insert into my_users values (2, 'Sam', '[email protected]');
insert into my_users values (3, 'Tom', '[email protected]');
insert into my_users values (4, 'Bob', '[email protected]');
insert into my_users values (5, 'Tom', '[email protected]');
commit;
select *
from my_users
where rowid not in (select min(rowid) from my_users group by name, email);
Dacă doriți pentru a vedea dacă există orice duplicat rânduri în tabel, am folosit de mai jos Interogare:
create table my_table(id int, name varchar(100), email varchar(100));
insert into my_table values (1, 'shekh', '[email protected]');
insert into my_table values (1, 'shekh', '[email protected]');
insert into my_table values (2, 'Aman', '[email protected]');
insert into my_table values (3, 'Tom', '[email protected]');
insert into my_table values (4, 'Raj', '[email protected]');
Select COUNT(1) As Total_Rows from my_table
Select Count(1) As Distinct_Rows from ( Select Distinct * from my_table) abc
Acest lucru este cel mai ușor lucru am'am venit cu. Se folosește o masă comună de exprimare (CTE) și o partiție fereastră (cred că aceste caracteristici sunt în SQL 2008 și mai târziu).
Acest exemplu găsește toți elevii cu duplicat numele și data nașterii. Câmpurile pe care doriți să verificați pentru dublarea merge în PESTE clauză. Puteți include orice alte domenii pe care doriți în proiecție.
with cte (StudentId, Fname, LName, DOB, RowCnt)
as (
SELECT StudentId, FirstName, LastName, DateOfBirth as DOB, SUM(1) OVER (Partition By FirstName, LastName, DateOfBirth) as RowCnt
FROM tblStudent
)
SELECT * from CTE where RowCnt > 1
ORDER BY DOB, LName
Prin Utilizarea CTE, de asemenea, putem găsi duplicat valoare ca acest
with MyCTE
as
(
select Name,EmailId,ROW_NUMBER() over(PARTITION BY EmailId order by id) as Duplicate from [Employees]
)
select * from MyCTE where Duplicate>1
Acest lucru ar trebui, de asemenea, locul de muncă, poate să-l încercați.
Select * from Users a
where EXISTS (Select * from Users b
where ( a.name = b.name
OR a.email = b.email)
and a.ID != b.id)
Deosebit de bun în cazul dumneavoastră Dacă veți căuta pentru copii care au un fel de prefix sau schimbare generală, ca de exemplu de domeniu nou în mail. apoi, puteți utiliza înlocui() la aceste coloane