varchar列のあるテーブルがあり、この列に重複する値を持つすべてのレコードを検索したいと思います。重複を見つけるために使用できる最良のクエリは何ですか?
varchar列のあるテーブルがあり、この列に重複する値を持つすべてのレコードを検索したいと思います。重複を見つけるために使用できる最良のクエリは何ですか?
回答:
やるSELECT
とGROUP BY
句。名前が重複を検索したい列であるとしましょう:
SELECT name, COUNT(*) c FROM table GROUP BY name HAVING c > 1;
これにより、最初の列に名前の値を含む結果が返され、その値が2番目の列に出現した回数が返されます。
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
)
このクエリは、個別varchar_column
のレコードだけでなく、完全なレコードを返します。
このクエリはを使用しませんCOUNT(*)
。重複が多数あり、COUNT(*)
コストが高く、全体を必要としない場合はCOUNT(*)
、同じ値の行が2つあるかどうかを確認するだけです。
varchar_column
もちろん、意志にインデックスがあると、このクエリが大幅に高速化されます。
ORDER BY varchar_column DESC
クエリの最後に追加しました。
GROUP BY
をHAVING
返すので、受け入れられた答えである必要があります。また、の代わりにインデックス付きフィールドを使用したパフォーマンスCOUNT(*)
、およびORDER BY
重複レコードをグループ化する可能性。
重複する行のIDを取得するためのlevikの回答を基にしてGROUP_CONCAT
、サーバーがサポートしている場合に実行できます(これにより、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 `dps`
WHERE pid IN (SELECT pid FROM `dps` GROUP BY pid HAVING COUNT(pid)>1)
従業員の名前列で重複しているレコードの数を見つけるには、以下のクエリが役立ちます。
Select name from employee group by name having count(*)>1;
重複を含むすべてのデータを取得するには、これを使用しました:
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アプローチは見ていません。
このアプローチでは、実際に2倍の結果が得られます。
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のワークベンチを:
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 ...
ですか?あなたの解決策の少しの説明は素晴らしいでしょう。
1つの非常に遅い貢献...それが誰かを助けてくれる場合に備えて...銀行アプリで一致するトランザクションのペア(実際にはアカウント間の送金の両側)を見つけて、どのトランザクションを識別するかというタスクがありました各アカウント間転送トランザクションの「from」と「to」であったため、次のようになりました。
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
は一致する(つまり重複する)トランザクションを含む行を提供しますが、同じペアが2回目に一致するときには同じトランザクションIDを逆に提供するためSELECT
、最初のトランザクションIDでグループ化するために外部が存在します。LEAST
およびGREATEST
を使用して、2つのトランザクションIDが結果で常に同じ順序になるようにします。これGROUP
により、最初のトランザクションIDが安全になり、重複するすべての一致が排除されます。100万近くのレコードを調べ、わずか2秒足らずで12,000以上の一致を特定しました。もちろん、transactionidはプライマリインデックスであり、これは本当に役立ちました。
SELECT ColumnA, COUNT( * )
FROM Table
GROUP BY ColumnA
HAVING COUNT( * ) > 1
重複使用を削除したい場合 DISTINCT
それ以外の場合は、次のクエリを使用します。
SELECT users.*,COUNT(user_ID) as user FROM users GROUP BY user_name HAVING user > 1;