varchar 열이있는 테이블이 있으며이 열에 중복 값이있는 모든 레코드를 찾고 싶습니다. 중복을 찾기 위해 사용할 수있는 가장 좋은 쿼리는 무엇입니까?
varchar 열이있는 테이블이 있으며이 열에 중복 값이있는 모든 레코드를 찾고 싶습니다. 중복을 찾기 위해 사용할 수있는 가장 좋은 쿼리는 무엇입니까?
답변:
를 수행 SELECT
로모그래퍼 GROUP BY
절. name 이 중복을 찾으려는 열 이라고 가정 해 봅시다 .
SELECT name, COUNT(*) c FROM table GROUP BY name HAVING c > 1;
첫 번째 열에 이름 값 이있는 결과와 두 번째 값에 해당 값이 몇 번 나타나는지를 반환합니다 .
GROUP_CONCAT(id)
ID를 나열합니다. 예를 들어 내 대답을 참조하십시오.
ERROR: column "c" does not exist LINE 1
할까요?
SELECT varchar_col
FROM table
GROUP BY varchar_col
HAVING COUNT(*) > 1;
IN()
/ 와 함께 사용하기에 유용합니다 NOT IN()
.
SELECT *
FROM mytable mto
WHERE EXISTS
(
SELECT 1
FROM mytable mti
WHERE mti.varchar_column = mto.varchar_column
LIMIT 1, 1
)
이 쿼리는 distinct뿐만 아니라 완전한 레코드를 반환합니다 varchar_column
.
이 검색어는을 사용하지 않습니다 COUNT(*)
. 중복이 많고 COUNT(*)
비싸고 전체가 필요하지 않은 COUNT(*)
경우 동일한 값을 가진 두 개의 행이 있는지 알아야합니다.
varchar_column
물론 인덱스를 사용 하면이 쿼리 속도가 크게 향상됩니다.
ORDER BY varchar_column DESC
쿼리 끝에 추가 했습니다.
GROUP BY
하고 HAVING
가능한 중복의 한으로 돌아갑니다. 또한 대신 색인 필드를 사용한 성능 COUNT(*)
및 ORDER BY
중복 레코드를 그룹화 할 수 있습니다.
GROUP_CONCAT
서버가 지원 하는 경우 중복 행의 ID를 얻기 위해 levik의 답변을 토대로 쉼표로 구분 된 ID 목록을 반환합니다.
SELECT GROUP_CONCAT(id), name, COUNT(*) c FROM documents GROUP BY name HAVING c > 1;
SELECT id, GROUP_CONCAT(id), name, COUNT(*) c [...]
인라인 편집이 가능하고 관련된 모든 행 (또는 적어도 첫 번째 행과 일치)을 업데이트해야하지만 불행히도 편집시 Javascript 오류가 발생합니다. ..
테이블 이름이 TableABC이고 원하는 열이 Col이고 T1의 기본 키가 Key라고 가정합니다.
SELECT a.Key, b.Key, a.Col
FROM TableABC a, TableABC b
WHERE a.Col = b.Col
AND a.Key <> b.Key
위의 답변에 비해이 방법의 장점은 키를 제공한다는 것입니다.
중복이 포함 된 모든 데이터를 얻으려면 이것을 사용했습니다.
SELECT * FROM TableName INNER JOIN(
SELECT DupliactedData FROM TableName GROUP BY DupliactedData HAVING COUNT(DupliactedData) > 1 order by DupliactedData)
temp ON TableName.DupliactedData = temp.DupliactedData;
TableName = 작업중인 테이블입니다.
DupliactedData = 찾고있는 중복 데이터
중복 측면에서 많은 용도로 사용되는 JOIN 방식이 표시되지 않습니다.
이 방법은 실제 두 배의 결과를 제공합니다.
SELECT t1.* FROM my_table as t1
LEFT JOIN my_table as t2
ON t1.name=t2.name and t1.id!=t2.id
WHERE t2.id IS NOT NULL
ORDER BY t1.name
@ maxyfc의 답변을 더 가져 가면 중복 값으로 반환 된 모든 행 을 찾아야 하므로 MySQL Workbench 에서 편집 할 수 있습니다 .
SELECT * FROM table
WHERE field IN (
SELECT field FROM table GROUP BY field HAVING count(*) > 1
) ORDER BY field
위의 결과를 보았고 중복 된 단일 열 값을 확인 해야하는 경우 쿼리가 제대로 작동합니다. 예를 들어 이메일.
그러나 더 많은 열을 확인해야하고 결과 조합을 확인하려면이 쿼리가 제대로 작동합니다.
SELECT COUNT(CONCAT(name,email)) AS tot,
name,
email
FROM users
GROUP BY CONCAT(name,email)
HAVING tot>1 (This query will SHOW the USER list which ARE greater THAN 1
AND also COUNT)
SELECT COUNT(CONCAT(userid,event,datetime)) AS total, userid, event, datetime FROM mytable GROUP BY CONCAT(userid, event, datetime ) HAVING total>1
전체 행을 볼 수 있기 때문에 창 함수 (MySQL 8.0 이상)를 사용하여 중복 항목을 찾는 것이 좋습니다.
WITH cte AS (
SELECT *
,COUNT(*) OVER(PARTITION BY col_name) AS num_of_duplicates_group
,ROW_NUMBER() OVER(PARTITION BY col_name ORDER BY col_name2) AS pos_in_group
FROM table
)
SELECT *
FROM cte
WHERE num_of_duplicates_group > 1;
SELECT
t.*,
(SELECT COUNT(*) FROM city AS tt WHERE tt.name=t.name) AS count
FROM `city` AS t
WHERE
(SELECT count(*) FROM city AS tt WHERE tt.name=t.name) > 1 ORDER BY count DESC
다음은 두 번 이상 사용 된 모든 product_id를 찾습니다. 각 product_id에 대해 하나의 레코드 만 얻습니다.
SELECT product_id FROM oc_product_reward GROUP BY product_id HAVING count( product_id ) >1
코드 : http://chandreshrana.blogspot.in/2014/12/find-duplicate-records-based-on-any.html
CREATE TABLE tbl_master
(`id` int, `email` varchar(15));
INSERT INTO tbl_master
(`id`, `email`) VALUES
(1, 'test1@gmail.com'),
(2, 'test2@gmail.com'),
(3, 'test1@gmail.com'),
(4, 'test2@gmail.com'),
(5, 'test5@gmail.com');
QUERY : SELECT id, email FROM tbl_master
WHERE email IN (SELECT email FROM tbl_master GROUP BY email HAVING COUNT(id) > 1)
SELECT DISTINCT a.email FROM `users` a LEFT JOIN `users` b ON a.email = b.email WHERE a.id != b.id;
a.email
하여 a.*
가져올 수있었습니다 .
SELECT DISTINCT a.*
거의 즉시 해결 되도록 변경했습니다 .
여러 개의 필드가있는 중복 행을 제거하려면 먼저 고유 한 행에만 지정된 새 고유 키에 해당 행을 할당 한 다음 "group by"명령을 사용하여 동일한 새 고유 키로 중복 행을 제거하십시오.
Create TEMPORARY table tmp select concat(f1,f2) as cfs,t1.* from mytable as t1;
Create index x_tmp_cfs on tmp(cfs);
Create table unduptable select f1,f2,... from tmp group by cfs;
CREATE TEMPORARY TABLE ...
않습니까? 솔루션에 대한 약간의 설명이 좋을 것입니다.
매우 늦게 기여한 것 중 하나입니다. 누구나 도움이 될 경우를 대비해서 ... 은행 거래 앱에서 일치하는 거래 쌍 (실제로 계좌 대 계좌 이체)을 찾아서 어떤 거래인지 식별하는 작업이있었습니다. 계정 간 이체 거래마다 '보낸 사람'과 '받는 사람'이되었으므로 결과는 다음과 같습니다.
SELECT
LEAST(primaryid, secondaryid) AS transactionid1,
GREATEST(primaryid, secondaryid) AS transactionid2
FROM (
SELECT table1.transactionid AS primaryid,
table2.transactionid AS secondaryid
FROM financial_transactions table1
INNER JOIN financial_transactions table2
ON table1.accountid = table2.accountid
AND table1.transactionid <> table2.transactionid
AND table1.transactiondate = table2.transactiondate
AND table1.sourceref = table2.destinationref
AND table1.amount = (0 - table2.amount)
) AS DuplicateResultsTable
GROUP BY transactionid1
ORDER BY transactionid1;
결과는 DuplicateResultsTable
일치하는 (즉, 중복 된) 트랜잭션을 포함하는 행을 제공하지만 동일한 쌍과 일치 할 때 두 번째로 동일한 트랜잭션 ID를 반대로 제공하므로 외부 SELECT
는 첫 번째 트랜잭션 ID별로 그룹화됩니다. 사용하여 LEAST
및 GREATEST
확인이 개는 TransactionId의 정보는 다음의 제품에 안전하게 만드는 결과 같은 순서에 항상 있도록 GROUP
따라서 모든 중복 일치를 제거, 최초의 하나. 거의 백만 건의 기록을 뚫고 2 초 이내에 12,000 건 이상의 경기를 확인했습니다. 물론 transactionid는 기본 인덱스이며 실제로 도움이되었습니다.
중복 사용을 제거하려면 DISTINCT
그렇지 않으면이 쿼리를 사용하십시오.
SELECT users.*,COUNT(user_ID) as user FROM users GROUP BY user_name HAVING user > 1;