Mam tabelę z kolumną varchar i chciałbym znaleźć wszystkie rekordy, które mają zduplikowane wartości w tej kolumnie. Jakiego zapytania najlepiej użyć do znalezienia duplikatów?
Mam tabelę z kolumną varchar i chciałbym znaleźć wszystkie rekordy, które mają zduplikowane wartości w tej kolumnie. Jakiego zapytania najlepiej użyć do znalezienia duplikatów?
Odpowiedzi:
Zrób SELECT
z GROUP BY
klauzulą. Powiedzmy, że nazwa to kolumna, w której chcesz znaleźć duplikaty:
SELECT name, COUNT(*) c FROM table GROUP BY name HAVING c > 1;
Zwróci to wynik z wartością nazwy w pierwszej kolumnie i liczbą wyświetleń tej wartości w drugiej kolumnie.
GROUP_CONCAT(id)
a wyświetli się lista identyfikatorów. Zobacz moją odpowiedź na przykład.
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
)
To zapytanie zwraca pełne rekordy, a nie tylko odrębne varchar_column
.
To zapytanie nie używa COUNT(*)
. Jeśli jest wiele duplikatów, COUNT(*)
jest kosztowne i nie potrzebujesz całości COUNT(*)
, musisz tylko wiedzieć, czy są dwa wiersze o tej samej wartości.
Posiadanie indeksu varchar_column
przyspieszy oczywiście to zapytanie.
ORDER BY varchar_column DESC
na końcu zapytania.
GROUP BY
i HAVING
powraca tylko jeden z możliwych duplikatów. Ponadto wydajność z polem indeksowanym zamiast COUNT(*)
oraz możliwość ORDER BY
grupowania zduplikowanych rekordów.
Opierając się na odpowiedzi Levika, aby uzyskać identyfikatory zduplikowanych wierszy, możesz zrobić a, GROUP_CONCAT
jeśli Twój serwer to obsługuje (zwróci listę identyfikatorów oddzielonych przecinkami).
SELECT GROUP_CONCAT(id), name, COUNT(*) c FROM documents GROUP BY name HAVING c > 1;
SELECT id, GROUP_CONCAT(id), name, COUNT(*) c [...]
umożliwia on edycję bezpośrednią i powinien zaktualizować wszystkie zaangażowane wiersze (lub przynajmniej pierwszy dopasowany), ale niestety edycja generuje błąd JavaScript. ..
Zakładając, że twoja tabela ma nazwę TableABC, a kolumna, którą chcesz, to Col, a klucz podstawowy do T1 to Key.
SELECT a.Key, b.Key, a.Col
FROM TableABC a, TableABC b
WHERE a.Col = b.Col
AND a.Key <> b.Key
Przewagą tego podejścia nad powyższą odpowiedzią jest to, że daje on Klucz.
Aby dowiedzieć się, ile rekordów jest duplikatami w kolumnie z nazwami w Pracowniku, pomocne jest poniższe zapytanie;
Select name from employee group by name having count(*)>1;
aby uzyskać wszystkie dane, które zawierają duplikację, użyłem tego:
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 = tabela, z którą pracujesz.
DupliactedData = zduplikowane dane, których szukasz.
Moje ostatnie zapytanie zawierało kilka odpowiedzi, które pomogły - łączenie grupy według, liczenia i GROUP_CONCAT.
SELECT GROUP_CONCAT(id), `magento_simple`, COUNT(*) c
FROM product_variant
GROUP BY `magento_simple` HAVING c > 1;
Podaje to identyfikator obu przykładów (oddzielonych przecinkami), potrzebny kod kreskowy i liczbę duplikatów.
Zmień odpowiednio tabelę i kolumny.
Nie widzę żadnych podejść do JOIN, które mają wiele zastosowań pod względem duplikatów.
Takie podejście daje rzeczywiste podwojone wyniki.
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
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
Zastąp miasto swoim stołem. Zastąp nazwę swoją nazwą pola
Biorąc dalej odpowiedź @ maxyfc , musiałem znaleźć wszystkie wiersze, które zostały zwrócone ze zduplikowanymi wartościami, aby móc je edytować w MySQL Workbench :
SELECT * FROM table
WHERE field IN (
SELECT field FROM table GROUP BY field HAVING count(*) > 1
) ORDER BY field
Widziałem powyższy wynik i zapytanie będzie działać poprawnie, jeśli chcesz sprawdzić wartość jednej kolumny, która jest zduplikowana. Na przykład e-mail.
Ale jeśli musisz sprawdzić więcej kolumn i chcesz sprawdzić kombinację wyniku, aby zapytanie działało poprawnie:
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
Wolę używać funkcji okienkowych (MySQL 8.0+) do znajdowania duplikatów, ponieważ widziałem cały wiersz:
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
Poniżej znajdziesz wszystkie id_produktu, które są używane więcej niż jeden raz. Otrzymujesz tylko jeden rekord dla każdego id_produktu.
SELECT product_id FROM oc_product_reward GROUP BY product_id HAVING count( product_id ) >1
Kod pochodzi z: 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
się a.*
i uzyskać wszystkie identyfikatory wierszy z duplikatów.
SELECT DISTINCT a.*
prawie natychmiastowa.
Aby usunąć zduplikowane wiersze z wieloma polami, najpierw anuluj je do nowego unikalnego klucza określonego dla jedynych odrębnych wierszy, a następnie użyj polecenia „grupuj”, aby usunąć zduplikowane wiersze z tym samym nowym unikalnym kluczem:
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 ...
? Świetne byłoby krótkie wyjaśnienie twojego rozwiązania.
Jeden bardzo spóźniony wkład ... na wypadek, gdyby to pomogło każdemu zejść w dół linii ... Miałem zadanie znaleźć pasujące pary transakcji (właściwie obie strony przelewów między rachunkami) w aplikacji bankowej, aby zidentyfikować, które z nich były „z” i „do” dla każdej transakcji przeniesienia między kontami, więc skończyliśmy na tym:
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;
W rezultacie DuplicateResultsTable
wiersze zawierające pasujące (tj. Zduplikowane) transakcje zapewniają również te same identyfikatory transakcji w odwrotnej kolejności za drugim razem, gdy dopasowuje tę samą parę, więc element zewnętrzny SELECT
może grupować według pierwszego identyfikatora transakcji, który jest wykonywany za pomocą LEAST
i, GREATEST
aby upewnić się, że dwa transakcje są zawsze w tej samej kolejności w wynikach, dzięki czemu jest bezpieczny GROUP
przez pierwszy, eliminując w ten sposób wszystkie duplikaty dopasowań. Przejrzał prawie milion rekordów i zidentyfikował ponad 12 000 meczów w niecałe 2 sekundy. Oczywiście transakcja jest głównym indeksem, który naprawdę pomógł.
Select column_name, column_name1,column_name2, count(1) as temp from table_name group by column_name having temp > 1
SELECT ColumnA, COUNT( * )
FROM Table
GROUP BY ColumnA
HAVING COUNT( * ) > 1
Jeśli chcesz usunąć zduplikowane użycie DISTINCT
W przeciwnym razie użyj tego zapytania:
SELECT users.*,COUNT(user_ID) as user FROM users GROUP BY user_name HAVING user > 1;
Spróbuj użyć tego zapytania:
SELECT name, COUNT(*) value_count FROM company_master GROUP BY name HAVING value_count > 1;