질문자 :Alex
하나의 필드로 중복 항목을 쉽게 찾을 수 있습니다.
SELECT name, COUNT(email) FROM users GROUP BY email HAVING COUNT(email) > 1
그래서 테이블이 있다면
ID NAME EMAIL 1 John asd@asd.com 2 Sam asd@asd.com 3 Tom asd@asd.com 4 Bob bob@asd.com 5 Tom asd@asd.com
email
가지고 있기 때문에 John, Sam, Tom, Tom을 제공합니다.
그러나 내가 원하는 것은 동일한 email
과 name
중복을 얻는 것입니다.
즉, "Tom", "Tom"을 얻고 싶습니다.
내가 이것을 필요로 하는 이유: 나는 실수를 했고, 중복된 name
과 email
값을 삽입하는 것을 허용했습니다. 이제 중복을 제거/변경해야 하므로 먼저 찾아야 합니다.
SELECT name, email, COUNT(*) FROM users GROUP BY name, email HAVING COUNT(*) > 1
두 열을 모두 그룹화하기만 하면 됩니다.
참고: 이전 ANSI 표준은 GROUP BY에 집계되지 않은 모든 열을 포함하는 것이지만 "기능적 종속성" 이라는 개념으로 변경되었습니다.
관계형 데이터베이스 이론에서 기능적 종속성은 데이터베이스의 관계에 있는 두 속성 집합 간의 제약 조건입니다. 즉, 기능적 종속성은 관계에서 속성 간의 관계를 설명하는 제약 조건입니다.
지원이 일관되지 않음:
- 최근 PostgreSQL 은 이를 지원합니다 .
- SQL Server(SQL Server 2017에서와 같이)는 여전히 GROUP BY에 집계되지 않은 모든 열이 필요합니다.
- MySQL은 예측할 수 없으며
sql_mode=only_full_group_by
가 필요합니다. - Oracle은 충분히 주류가 아닙니다(경고: 유머, 저는 Oracle에 대해 잘 모릅니다).
gbn이 시도:
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
산출:
name email CountOf ---------- ----------- ----------- John John-email 2 sam sam-email 2 (2 row(s) affected)
dups의 ID를 원하면 다음을 사용하십시오.
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
산출:
id name email ----------- ---------- ------------ 1 John John-email 2 John John-email 5 sam sam-email 6 sam sam-email (4 row(s) affected)
중복을 삭제하려면 다음을 시도하십시오.
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
산출:
id name email ----------- ---------- -------------- 1 John John-email 3 fred John-email 4 fred fred-email 5 sam sam-email (4 row(s) affected)
KM.이 시도:
SELECT name, email FROM users GROUP BY name, email HAVING ( COUNT(*) > 1 )
Chris Van Opstal중복을 삭제하려면 짝수/홀수 행을 트리플 하위 선택으로 찾는 것보다 훨씬 간단한 방법이 있습니다.
SELECT id, name, email FROM users u, users u2 WHERE u.name = u2.name AND u.email = u2.email AND u.id > u2.id
삭제하려면 다음을 수행합니다.
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 )
훨씬 더 읽기 쉽고 이해하기 쉬운 IMHO
참고: 유일한 문제는 매번 각 중복 항목 중 하나만 삭제하기 때문에 삭제된 행이 없을 때까지 요청을 실행해야 한다는 것입니다.
Tancrede Chazallet다른 답변과 달리 모든 열이 있는 경우 모든 열을 포함 하는 전체 레코드를 볼 수 있습니다. row_number 함수의 PARTITION BY
부분에서 원하는 고유/중복 열을 선택합니다.
SELECT * FROM ( SELECT a.* , Row_Number() OVER (PARTITION BY Name, Age ORDER BY Name) AS r FROM Customers AS a ) AS b WHERE r > 1;
모든 필드가 있는 모든 중복 레코드를 선택하려면 다음과 같이 작성할 수 있습니다.
CREATE TABLE test ( id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY , c1 integer , c2 text , d date DEFAULT now() , v text ); INSERT INTO test (c1, c2, v) VALUES (1, 'a', 'Select'), (1, 'a', 'ALL'), (1, 'a', 'multiple'), (1, 'a', 'records'), (2, 'b', 'in columns'), (2, 'b', 'c1 and c2'), (3, 'c', '.'); SELECT * FROM test ORDER BY 1; SELECT * FROM test WHERE (c1, c2) IN ( SELECT c1, c2 FROM test GROUP BY 1,2 HAVING count(*) > 1 ) ORDER BY 1;
PostgreSQL 에서 테스트되었습니다.
gaurav singh SELECT name, email FROM users WHERE email in (SELECT email FROM users GROUP BY email HAVING COUNT(*)>1)
PRADEEPTA VIRLLEY파티에 조금 늦었지만 모든 중복 ID를 찾는 정말 멋진 해결 방법을 찾았습니다.
SELECT email, GROUP_CONCAT(id) FROM users GROUP BY email HAVING COUNT(email) > 1;
Indivision Dev이것은 각 중복 그룹에서 하나의 레코드를 제외한 모든 중복 레코드를 선택/삭제합니다. 따라서 삭제는 모든 고유 레코드 + 각 중복 그룹에서 하나의 레코드를 남깁니다.
중복 선택:
SELECT * FROM table WHERE id NOT IN ( SELECT MIN(id) FROM table GROUP BY column1, column2 );
중복 삭제:
DELETE FROM table WHERE id NOT IN ( SELECT MIN(id) FROM table GROUP BY column1, column2 );
더 많은 양의 레코드를 인식하면 성능 문제가 발생할 수 있습니다.
Martin Silovský이 코드를 시도
WITH CTE AS ( SELECT Id, Name, Age, Comments, RN = ROW_NUMBER()OVER(PARTITION BY Name,Age ORDER BY ccn) FROM ccnmaster ) select * from CTE
Tanmay NeheteOracle과 함께 작업하는 경우 다음 방법이 바람직합니다.
create table my_users(id number, name varchar2(100), email varchar2(100)); insert into my_users values (1, 'John', 'asd@asd.com'); insert into my_users values (2, 'Sam', 'asd@asd.com'); insert into my_users values (3, 'Tom', 'asd@asd.com'); insert into my_users values (4, 'Bob', 'bob@asd.com'); insert into my_users values (5, 'Tom', 'asd@asd.com'); commit; select * from my_users where rowid not in (select min(rowid) from my_users group by name, email);
xDBAselect name, email , case when ROW_NUMBER () over (partition by name, email order by name) > 1 then 'Yes' else 'No' end "duplicated ?" from users
Narendra테이블에 중복 행이 있는지 확인하려면 아래 쿼리를 사용했습니다.
create table my_table(id int, name varchar(100), email varchar(100)); insert into my_table values (1, 'shekh', 'shekh@rms.com'); insert into my_table values (1, 'shekh', 'shekh@rms.com'); insert into my_table values (2, 'Aman', 'aman@rms.com'); insert into my_table values (3, 'Tom', 'tom@rms.com'); insert into my_table values (4, 'Raj', 'raj@rms.com'); Select COUNT(1) As Total_Rows from my_table Select Count(1) As Distinct_Rows from ( Select Distinct * from my_table) abc
shekhar KumarSELECT id, COUNT(id) FROM table1 GROUP BY id HAVING COUNT(id)>1;
특정 열에서 반복되는 값을 검색하는 데 이것이 제대로 작동할 것이라고 생각합니다.
user4877838
select id,name,COUNT(*) from user group by Id,Name having COUNT(*)>1
Debendra Dash select emp.ename, emp.empno, dept.loc from emp inner join dept on dept.deptno=emp.deptno inner join (select ename, count(*) from emp group by ename, deptno having count(*) > 1) t on emp.ename=t.ename order by emp.ename /
naveed이것은 내가 생각해 낸 쉬운 것입니다. CTE(공통 테이블 표현식)와 파티션 창을 사용합니다(이러한 기능은 SQL 2008 이상에 있다고 생각합니다).
이 예에서는 이름과 dob가 중복된 모든 학생을 찾습니다. 중복 여부를 확인하려는 필드는 OVER 절로 이동합니다. 투영에 원하는 다른 필드를 포함할 수 있습니다.
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
Darrel Lee어떻게 중복된 값을 계산할 수 있습니까?? 2번 또는 2번 이상 반복됩니다. 그룹 단위가 아닌 그냥 세십시오.
간단한
select COUNT(distinct col_01) from Table_01
Muhammad TahirCTE를 사용하여 다음과 같은 중복 값도 찾을 수 있습니다.
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
Debendra Dash이것도 작동해야 합니다. 시도해 보세요.
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)
귀하의 경우에 특히 좋습니다. 예를 들어 메일의 새 도메인과 같이 일종의 접두사 또는 일반적인 변경이 있는 중복 항목을 검색하는 경우. 그런 다음 이러한 열에서 replace()를 사용할 수 있습니다.
veritaSSELECT * FROM users u where rowid = (select max(rowid) from users u1 where u.email=u1.email);
Panky031SELECT name, email,COUNT(email) FROM users WHERE email IN ( SELECT email FROM users GROUP BY email HAVING COUNT(email) > 1)
Mohammad Neamul Islam여기서 가장 중요한 것은 가장 빠른 기능을 갖는 것입니다. 또한 중복 인덱스를 식별해야 합니다. 자체 조인도 좋은 옵션이지만 더 빠른 기능을 사용하려면 먼저 중복된 행을 찾은 다음 원본 테이블과 조인하여 중복된 행의 ID를 찾는 것이 좋습니다. 마지막으로 id를 제외한 모든 열을 기준으로 정렬하여 서로 가까이에 중복된 행을 갖습니다.
SELECT u.* FROM users AS u JOIN (SELECT username, email FROM users GROUP BY username, email HAVING COUNT(*)>1) AS w ON u.username=w.username AND u.email=w.email ORDER BY u.email;
RyanAbnavi중복 데이터(하나 또는 여러 기준으로)를 찾고 실제 행을 선택하려는 경우.
with MYCTE as ( SELECT DuplicateKey1 ,DuplicateKey2 --optional ,count(*) X FROM MyTable group by DuplicateKey1, DuplicateKey2 having count(*) > 1 ) SELECT E.* FROM MyTable E JOIN MYCTE cte ON E.DuplicateKey1=cte.DuplicateKey1 AND E.DuplicateKey2=cte.DuplicateKey2 ORDER BY E.DuplicateKey1, E.DuplicateKey2, CreatedAt
http://developer.azurewebsites.net/2014/09/better-sql-group-by-find-duplicate-data/
Lauri Lubi이름이 중복된 레코드를 삭제하려면
;WITH CTE AS ( SELECT ROW_NUMBER() OVER (PARTITION BY name ORDER BY name) AS T FROM @YourTable ) DELETE FROM CTE WHERE T > 1
Sheriff테이블의 중복 레코드에서 확인하려면.
select * from users s where rowid < any (select rowid from users k where s.name = k.name and s.email = k.email);
또는
select * from users s where rowid not in (select max(rowid) from users k where s.name = k.name and s.email = k.email);
테이블에서 중복 레코드를 삭제하려면.
delete from users s where rowid < any (select rowid from users k where s.name = k.name and s.email = k.email);
또는
delete from users s where rowid not in (select max(rowid) from users k where s.name = k.name and s.email = k.email);
Arun Solomon분석 기능을 사용하여 이것을 시도할 수 있는 또 다른 쉬운 방법은 다음과 같습니다.
SELECT * from (SELECT name, email, COUNT(name) OVER (PARTITION BY name, email) cnt FROM users) WHERE cnt >1;
The AG
SELECT column_name,COUNT(*) FROM TABLE_NAME GROUP BY column1, HAVING COUNT(*) > 1;
rahul kumar이것을 시도하고 싶을 수도 있습니다.
SELECT NAME, EMAIL, COUNT(*) FROM USERS GROUP BY 1,2 HAVING COUNT(*) > 1
adesh시도하십시오
SELECT UserID, COUNT(UserID) FROM dbo.User GROUP BY UserID HAVING COUNT(UserID) > 1
Md. Nazmul Nadim아래와 같이 집계 함수에서 작동하는 데 사용할 수 있습니다.
create table #TableB (id_account int, data int, [date] date) insert into #TableB values (1 ,-50, '10/20/2018'), (1, 20, '10/09/2018'), (2 ,-900, '10/01/2018'), (1 ,20, '09/25/2018'), (1 ,-100, '08/01/2018') SELECT id_account , data, COUNT(*) FROM #TableB GROUP BY id_account , data HAVING COUNT(id_account) > 1 drop table #TableB
여기에서 id_account와 data라는 두 개의 필드가 Count(*)와 함께 사용됩니다. 따라서 두 열에 동일한 값이 두 번 이상 있는 모든 레코드를 제공합니다.
우리는 실수로 SQL 서버 테이블에 제약 조건을 추가하는 것을 놓쳤고 레코드가 프런트 엔드 응용 프로그램이 있는 모든 열에 중복으로 삽입되었습니다. 그런 다음 아래 쿼리를 사용하여 테이블에서 중복 쿼리를 삭제할 수 있습니다.
SELECT DISTINCT * INTO #TemNewTable FROM #OriginalTable TRUNCATE TABLE #OriginalTable INSERT INTO #OriginalTable SELECT * FROM #TemNewTable DROP TABLE #TemNewTable
여기서 우리는 원본 테이블의 모든 개별 레코드를 가져오고 원본 테이블의 레코드를 삭제했습니다. 다시 우리는 새 테이블의 모든 고유 값을 원래 테이블에 삽입한 다음 새 테이블을 삭제했습니다.
Suraj Kumar출처 : http:www.stackoverflow.com/questions/2594829/finding-duplicate-values-in-a-sql-table