sql - 하나만 - 테이블 중복 데이터 제거




SQL 테이블에서 중복 값 찾기 (17)

다음을 시도하십시오.

SELECT * FROM
(
    SELECT Id, Name, Age, Comments, Row_Number() OVER(PARTITION BY Name, Age ORDER By Name)
        AS Rank 
        FROM Customers
) AS B WHERE Rank>1

하나의 필드로 duplicates 것을 쉽게 찾을 수 있습니다.

SELECT name, COUNT(email) 
FROM users
GROUP BY email
HAVING COUNT(email) > 1

그래서 테이블이 있다면

ID   NAME   EMAIL
1    John   [email protected]
2    Sam    [email protected]
3    Tom    [email protected]
4    Bob    [email protected]
5    Tom    [email protected]

이 쿼리는 John, Sam, Tom, Tom 모두에게 동일한 email 이 있기 때문에 제공됩니다.

그러나, 내가 원하는 것은 동일한 emailname 중복 된 것을 얻는 것입니다.

즉, 저는 "Tom", "Tom"을 얻고 싶습니다.

내가 이것을 필요로하는 이유 : 나는 실수를했고 중복되는 nameemail 값을 삽입하는 것을 허용했다. 이제 사본을 제거 / 변경 해야하므로 먼저 사본을 찾아야 합니다.


아래와 같이 집계 함수로 작업하는 것을 사용할 수 있습니다.

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 및 데이터가 Count (*)와 함께 사용됩니다. 따라서 두 열에 동일한 값이 두 번 이상있는 모든 레코드를 제공합니다.

우리는 실수로 SQL 서버 테이블에 제약 조건을 추가하지 않고 프런트 엔드 응용 프로그램이있는 모든 열에 레코드가 중복 삽입되었습니다. 그런 다음 아래 쿼리를 사용하여 테이블에서 중복 쿼리를 삭제할 수 있습니다.

SELECT DISTINCT * INTO #TemNewTable FROM #OriginalTable
TRUNCATE TABLE #OriginalTable
INSERT INTO #OriginalTable SELECT * FROM #TemNewTable
DROP TABLE #TemNewTable

여기서 우리는 orignal 테이블의 모든 별개 레코드를 가져 와서 원래 테이블의 레코드를 삭제했습니다. 다시 새 테이블의 모든 고유 값을 원래 테이블에 삽입 한 다음 새 테이블을 삭제했습니다.


이 시도:

SELECT name, email
FROM users
GROUP BY name, email
HAVING ( COUNT(*) > 1 )

이 시도:

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)

이것은 내가 생각해내는 쉬운 일입니다. 공통 테이블 식 (CTE)과 파티션 창을 사용합니다 (SQL Server 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

이것은 또한 작동해야합니다, 어쩌면 그것을 시도하십시오.

  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 ()를 사용할 수 있습니다.


중복 된 값을 어떻게 계산할 수 있습니까 ?? 그것은 2 번 또는 2 번 반복됩니다. 단지 그들을 카운트하고, 현명한 그룹은 아닙니다.

간단하게

select COUNT(distinct col_01) from Table_01

중복을 삭제하려면 짝수 / 홀수 행을 트리플 하위 선택으로 찾아야하는 것보다 훨씬 간단한 방법이 있습니다.

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를 읽고 이해하는 것이 훨씬 쉬워졌습니다.

참고 : 유일한 문제는 삭제 된 행이 없어 질 때까지 요청을 실행해야한다는 것입니다. 매번 각 복제본 중 하나만 삭제하기 때문입니다


파티가 좀 늦었지만 모든 중복 ID를 찾는 멋진 해결 방법을 발견했습니다.

SELECT GROUP_CONCAT( id )
FROM users
GROUP BY email
HAVING ( COUNT(email) > 1 )

하나 또는 여러 기준으로 중복 데이터를 찾고 실제 행을 선택하려는 경우

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/


SELECT id, COUNT(id) FROM table1 GROUP BY id HAVING COUNT(id)>1;

나는 이것이 특정 열의 반복 된 값을 검색하는 데 제대로 작동 할 것이라고 생각한다.


테이블에 중복 레코드를 얻는 방법

SELECT COUNT (코드), 직원 코드 WHERE 상태 = 1 GROUP BY 코드 COUNT (코드)> 1


 SELECT name, email 
    FROM users
    WHERE email in
    (SELECT email FROM users
    GROUP BY email 
    HAVING COUNT(*)>1)

 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
/

SELECT
  FirstName, LastName, MobileNo, COUNT(1) as CNT 
FROM        
  CUSTOMER
GROUP BY
  FirstName, LastName, MobileNo 
HAVING
  COUNT(1) > 1;

SELECT * FROM users u where rowid = (select max(rowid) from users u1 where
u.email=u1.email);

select name, email
, case 
when ROW_NUMBER () over (partition by name, email order by name) > 1 then 'Yes'
else 'No'
end "duplicated ?"
from users




duplicates