Tengo una tabla con una columna varchar, y me gustaría encontrar todos los registros que tienen valores duplicados en esta columna. ¿Cuál es la mejor consulta que puedo usar para encontrar los duplicados?
Pero, ¿cómo es esto útil si no puede obtener los ID de las filas con valores duplicados? Sí, puede hacer una nueva consulta que coincida para cada valor duplicado, pero ¿es posible simplemente enumerar los duplicados?
NobleUplift
23
@NobleUplift Puede hacer un GROUP_CONCAT(id)y mostrará una lista de las ID. Vea mi respuesta para un ejemplo.
Matt Rardon
55
¿Qué significaría si dijera ERROR: column "c" does not exist LINE 1?
Usuario
15
Estoy confundido por qué esta es la respuesta aceptada y por qué tiene tantos votos a favor. El OP preguntó: "Me gustaría encontrar todos los registros que tienen valores duplicados en esta columna". Esta respuesta devuelve una tabla de recuentos. -1
Monica Heddneck
44
Para aquellos que no entienden cómo funciona HAVING, es simplemente un filtro en el conjunto de resultados, por lo que sucede después de la consulta principal.
John Hunt
236
SELECT varchar_col
FROMtableGROUPBY varchar_col
HAVING COUNT(*)>1;
Superior a la respuesta de @ levik ya que no agrega una columna adicional. Lo hace útil para usar con IN()/ NOT IN().
wmassingham
172
SELECT*FROM mytable mto
WHEREEXISTS(SELECT1FROM mytable mti
WHERE mti.varchar_column = mto.varchar_column
LIMIT 1,1)
Esta consulta devuelve registros completos, no solo distintos varchar_column.
Esta consulta no usa COUNT(*). Si hay muchos duplicados, COUNT(*)es costoso y no necesita el todo COUNT(*), solo necesita saber si hay dos filas con el mismo valor.
Tener un índice en varchar_columnvoluntad, por supuesto, acelerará enormemente esta consulta.
Muy bien. Agregué ORDER BY varchar_column DESCal final de la consulta.
trante
8
Esta debe ser la respuesta aceptada, como GROUP BYy HAVINGdevoluciones solamente una de las posibles duplicados. Además, el rendimiento con un campo indexado en lugar de COUNT(*), y la posibilidad ORDER BYde agrupar registros duplicados.
Rémi Breton
1
Como se indicó en los comentarios anteriores, esta consulta le permite enumerar todas las filas duplicadas. Muy útil.
TryHarder
44
Mirando esto, no entiendo cómo funcionaría en absoluto. ¿La condición interna no siempre será verdadera ya que cualquier fila de la tabla externa también estará disponible en la tabla interna y, por lo tanto, cada fila siempre coincidirá por lo menos? Intenté la consulta y obtuve el resultado que sospechaba: cada fila regresaba. Pero con tantos votos positivos, dudo de mí mismo. ¿No le falta a la consulta interna algo como "AND mto.id <> mti.id"? A mí me funciona cuando agrego eso.
Clox
2
@Quassnoi Muy bien. Intenté ponerlo en sqlfiddle, pero me di por vencido ya que cada consulta que intento ejecutar, aparte de crear el esquema, se agota. Me di cuenta de que simplemente eliminar "EXISTS" también hace que la consulta funcione correctamente para mí.
Clox
144
A partir de la respuesta de levik para obtener los ID de las filas duplicadas, puede hacer GROUP_CONCATsi su servidor lo admite (esto devolverá una lista de identificadores separados por comas).
SELECT GROUP_CONCAT(id), name, COUNT(*) c FROM documents GROUPBY name HAVING c >1;
¡Todo este tiempo sin saber acerca de GROUP_CONCAT ()! Muy muy útil.
aesede
Realmente apreciado Matt. ¡Esto es realmente útil! Para aquellos que intentan actualizar en phpmyadmin si dejan la identificación junto con la función de esta manera: SELECT id, GROUP_CONCAT(id), name, COUNT(*) c [...]permite la edición en línea y debe actualizar todas las filas involucradas (o al menos la primera coincidente), pero desafortunadamente la edición genera un error de Javascript. ..
Armfoot
¿Cómo calcularía entonces cuántos identificadores están sujetos a duplicación?
CMCDragonkai
2
¿Cómo no obtengo todos los ID agrupados, sino que los enumero del primero al último? con todos sus valores respectivos en las columnas al lado de ellos? Entonces, en lugar de agruparlo, solo muestra ID 1 y su valor, ID 2 y su valor. INCLUSO si los valores para la ID son los mismos.
MailBlade
1
Respuesta extremadamente útil, esto debería ser superior para que más personas lo vean. Recuerdo cuánto dolor pasé creando tales listas, y estaba disponible todo el tiempo como comando ...
John
13
Suponiendo que su tabla se llama TableABC y la columna que desea es Col y la clave principal de T1 es Clave.
SELECT a.Key, b.Key, a.Col
FROM TableABC a, TableABC b
WHERE a.Col = b.Col
AND a.Key<> b.Key
La ventaja de este enfoque sobre la respuesta anterior es que proporciona la clave.
+1 Porque es útil. Aunque, irónicamente, el resultado en sí contiene duplicados (enumera a y b, luego b y a.)
Fabien Snauwaert
2
@FabienSnauwaert Puede deshacerse de algunos de los duplicados al comparar menos que (o más que)
Michael
@TechTravelThink su respuesta es muy clara, gracias por eso, pero en una tabla grande toma algo de tiempo (alrededor de 2 millones en más de 20'000 tablas de entradas) y después de mostrar 25 primeros resultados, si hago clic para mostrar la siguiente, phpmyadmin muestra error "# 1052 - La columna 'id' en la cláusula de pedido es ambigua "
bcag2
12
SELECT*FROM`dps`WHERE pid IN(SELECT pid FROM`dps`GROUPBY pid HAVING COUNT(pid)>1)
FYI: deseará 'seleccionar alguien diferente' si existe la posibilidad de que exista más de 1 registro duplicado; de lo contrario, los resultados contendrán duplicados de las filas duplicadas que se encontraron.
Dibujó el
7
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
)>1orderby count desc
Reemplace la ciudad con su mesa. Reemplace el nombre con el nombre de su campo
Tomando la respuesta de @ maxyfc más lejos, necesitaba encontrar todas las filas que fueron devueltas con los valores duplicados, para poder editarlas en MySQL Workbench :
SELECT*FROMtableWHERE field IN(SELECT field FROMtableGROUPBY field HAVING count(*)>1)ORDERBY field
Vi el resultado anterior y la consulta funcionará bien si necesita verificar el valor de una sola columna que está duplicado. Por ejemplo correo electrónico.
Pero si necesita verificar con más columnas y desea verificar la combinación del resultado para que esta consulta funcione bien:
SELECT COUNT(CONCAT(name,email))AS tot,
name,
email
FROM users
GROUPBY CONCAT(name,email)HAVING tot>1(This query will SHOW the USER list which ARE greater THAN 1AND also COUNT)
¡Exactamente lo que se necesitaba! Aquí mi consulta, verificando 3 campos para duplicados:SELECT COUNT(CONCAT(userid,event,datetime)) AS total, userid, event, datetime FROM mytable GROUP BY CONCAT(userid, event, datetime ) HAVING total>1
Kai Noack
4
Prefiero usar funciones de ventana (MySQL 8.0+) para encontrar duplicados porque pude ver toda la fila:
WITH cte AS(SELECT*,COUNT(*)OVER(PARTITIONBY col_name)AS num_of_duplicates_group
,ROW_NUMBER()OVER(PARTITIONBY col_name ORDERBY col_name2)AS pos_in_group
FROMtable)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)>1ORDERBY count DESC
Vale la pena señalar que esto es insoportablemente lento o incluso podría no terminar si la columna que se está consultando no está indexada. De lo contrario, yo era capaz de cambiar a.emaila a.*y obtener todos los ID de las filas con duplicados.
NobleUplift
@NobleUplift ¿De qué estás hablando?
Michael
@Michael Bueno, ya que esto tiene tres años, no puedo probar la versión de MySQL que estaba usando, pero intenté esta misma consulta en una base de datos donde la columna que seleccioné no tenía un índice, por lo que tomó bastante tiempo. Unos segundos para terminar. Cambiando a SELECT DISTINCT a.*resuelto casi al instante.
NobleUplift
@NobleUplift Ah, ok. Puedo entender que sea lento ... la parte que me preocupa es "quizás ni siquiera termine".
Michael
@Michael No recuerdo en qué tabla de nuestro sistema tuve que ejecutar esta consulta, pero para aquellos con algunos millones de registros probablemente habrían terminado, pero en un tiempo que tomó tanto tiempo que me di por vencido cuando En realidad terminaría.
NobleUplift
1
Para eliminar filas duplicadas con múltiples campos, primero puede asignarlas a la nueva clave única que se especifica para las únicas filas distintas, luego use el comando "agrupar por" para eliminar filas duplicadas con la misma clave única nueva:
Create TEMPORARY table tmp select concat(f1,f2)as cfs,t1.*from mytable as t1;Createindex x_tmp_cfs on tmp(cfs);Createtable unduptable select f1,f2,...from tmp groupby cfs;
¿Por qué no usar CREATE TEMPORARY TABLE ...? Una pequeña explicación de su solución sería genial.
maxhb
1
Una contribución muy tardía ... en caso de que ayude a alguien muuuucho más adelante ... Tuve la tarea de encontrar pares de transacciones coincidentes (en realidad, ambos lados de las transferencias de cuenta a cuenta) en una aplicación bancaria, para identificar cuáles fueron el 'desde' y el 'hasta' para cada transacción de transferencia entre cuentas, así que terminamos con esto:
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
INNERJOIN 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
GROUPBY transactionid1
ORDERBY transactionid1;
El resultado es que DuplicateResultsTableproporciona filas que contienen transacciones coincidentes (es decir, duplicadas), pero también proporciona los mismos ID de transacción a la inversa la segunda vez que coincide con el mismo par, por lo que el externo SELECTestá allí para agrupar por la primera ID de transacción, lo que se hace usando LEASTy GREATESTpara asegurarse de que los dos transaccionales estén siempre en el mismo orden en los resultados, lo que lo hace seguro para GROUPel primero, eliminando así todas las coincidencias duplicadas. Repasó casi un millón de registros e identificó más de 12,000 coincidencias en poco menos de 2 segundos. Por supuesto, el ID de transacción es el índice primario, lo que realmente ayudó.
Respuestas:
Haz un
SELECT
con unaGROUP BY
cláusula. Digamos que nombre es la columna en la que desea encontrar duplicados:Esto devolverá un resultado con el valor del nombre en la primera columna y un recuento de cuántas veces aparece ese valor en la segunda.
fuente
GROUP_CONCAT(id)
y mostrará una lista de las ID. Vea mi respuesta para un ejemplo.ERROR: column "c" does not exist LINE 1
?fuente
IN()
/NOT IN()
.Esta consulta devuelve registros completos, no solo distintos
varchar_column
.Esta consulta no usa
COUNT(*)
. Si hay muchos duplicados,COUNT(*)
es costoso y no necesita el todoCOUNT(*)
, solo necesita saber si hay dos filas con el mismo valor.Tener un índice en
varchar_column
voluntad, por supuesto, acelerará enormemente esta consulta.fuente
ORDER BY varchar_column DESC
al final de la consulta.GROUP BY
yHAVING
devoluciones solamente una de las posibles duplicados. Además, el rendimiento con un campo indexado en lugar deCOUNT(*)
, y la posibilidadORDER BY
de agrupar registros duplicados.A partir de la respuesta de levik para obtener los ID de las filas duplicadas, puede hacer
GROUP_CONCAT
si su servidor lo admite (esto devolverá una lista de identificadores separados por comas).fuente
SELECT id, GROUP_CONCAT(id), name, COUNT(*) c [...]
permite la edición en línea y debe actualizar todas las filas involucradas (o al menos la primera coincidente), pero desafortunadamente la edición genera un error de Javascript. ..Suponiendo que su tabla se llama TableABC y la columna que desea es Col y la clave principal de T1 es Clave.
La ventaja de este enfoque sobre la respuesta anterior es que proporciona la clave.
fuente
fuente
Para encontrar cuántos registros están duplicados en la columna de nombre en Empleado, la consulta a continuación es útil;
fuente
para obtener todos los datos que contienen duplicación, utilicé esto:
TableName = la tabla con la que está trabajando.
DupliactedData = los datos duplicados que está buscando.
fuente
Mi consulta final incorporó algunas de las respuestas que ayudaron: combinar group by, count & GROUP_CONCAT.
Esto proporciona la identificación de ambos ejemplos (separados por comas), el código de barras que necesitaba y cuántos duplicados.
Cambiar la tabla y las columnas en consecuencia.
fuente
No veo ningún enfoque JOIN, que tenga muchos usos en términos de duplicados.
Este enfoque le brinda resultados duplicados reales.
fuente
Reemplace la ciudad con su mesa. Reemplace el nombre con el nombre de su campo
fuente
Tomando la respuesta de @ maxyfc más lejos, necesitaba encontrar todas las filas que fueron devueltas con los valores duplicados, para poder editarlas en MySQL Workbench :
fuente
Vi el resultado anterior y la consulta funcionará bien si necesita verificar el valor de una sola columna que está duplicado. Por ejemplo correo electrónico.
Pero si necesita verificar con más columnas y desea verificar la combinación del resultado para que esta consulta funcione bien:
fuente
SELECT COUNT(CONCAT(userid,event,datetime)) AS total, userid, event, datetime FROM mytable GROUP BY CONCAT(userid, event, datetime ) HAVING total>1
Prefiero usar funciones de ventana (MySQL 8.0+) para encontrar duplicados porque pude ver toda la fila:
DB Fiddle Demo
fuente
fuente
Lo siguiente encontrará todos los product_id que se usan más de una vez. Solo obtiene un único registro para cada product_id.
Código tomado de: http://chandreshrana.blogspot.in/2014/12/find-duplicate-records-based-on-any.html
fuente
fuente
fuente
a.email
aa.*
y obtener todos los ID de las filas con duplicados.SELECT DISTINCT a.*
resuelto casi al instante.Para eliminar filas duplicadas con múltiples campos, primero puede asignarlas a la nueva clave única que se especifica para las únicas filas distintas, luego use el comando "agrupar por" para eliminar filas duplicadas con la misma clave única nueva:
fuente
CREATE TEMPORARY TABLE ...
? Una pequeña explicación de su solución sería genial.Una contribución muy tardía ... en caso de que ayude a alguien muuuucho más adelante ... Tuve la tarea de encontrar pares de transacciones coincidentes (en realidad, ambos lados de las transferencias de cuenta a cuenta) en una aplicación bancaria, para identificar cuáles fueron el 'desde' y el 'hasta' para cada transacción de transferencia entre cuentas, así que terminamos con esto:
El resultado es que
DuplicateResultsTable
proporciona filas que contienen transacciones coincidentes (es decir, duplicadas), pero también proporciona los mismos ID de transacción a la inversa la segunda vez que coincide con el mismo par, por lo que el externoSELECT
está allí para agrupar por la primera ID de transacción, lo que se hace usandoLEAST
yGREATEST
para asegurarse de que los dos transaccionales estén siempre en el mismo orden en los resultados, lo que lo hace seguro paraGROUP
el primero, eliminando así todas las coincidencias duplicadas. Repasó casi un millón de registros e identificó más de 12,000 coincidencias en poco menos de 2 segundos. Por supuesto, el ID de transacción es el índice primario, lo que realmente ayudó.fuente
fuente
fuente
Si desea eliminar el uso duplicado
DISTINCT
De lo contrario, use esta consulta:
SELECT users.*,COUNT(user_ID) as user FROM users GROUP BY user_name HAVING user > 1;
fuente
Intenta usar esta consulta:
fuente