2010-04-22 10 views
9

así que tengo una tabla de usuarios donde el user.username tiene muchos duplicados como:de casos duplicados insensibles SQL

username y Username y useRnAme
john y John y jOhn

Eso fue un error y estos tres los registros deberían haber sido solo uno.

Estoy tratando de llegar a una consulta SQL que muestra todos estos casos ordenados por su fecha de creación, por lo que idealmente el resultado debería ser algo como esto:

username jan01 
useRnAme jan02 
Username jan03 
john  feb01 
John  feb02 
jOhn  feb03 

será muy apreciada Cualquier sugerencia

+1

@hdx: Su pregunta está etiquetado 'mysql' y' postgresql'. ¿Estás usando ambos? –

+0

@hdx: ¿Estás almacenando las fechas en ese formato y no en una columna de fecha? –

+0

@Peter Lang, de hecho cualquier lenguaje similar a sql haría, puedo portarlo. Estoy usando postgresql. – hdx

Respuesta

22

Dejando de lado la cuestión de la sensibilidad caso por un momento, la estrategia básica es:

SELECT username, create_date FROM your_table 
    WHERE username IN 
    (SELECT username FROM your_table GROUP BY username HAVING COUNT(*) > 1) 
ORDER BY username, create_date 

Muchos RDBMSes (incluyendo MySQL suponiendo que está utilizando CHAR o VARCHAR para la columna de nombre de usuario), lleve a cabo entre mayúsculas y minúsculas buscando por defecto. Para esas bases de datos, la solución anterior funcionará. Para resolver el problema de la sensibilidad caso de otros productos, envuelva todos excepto la primera aparición del nombre de usuario en la función de conversión de mayúsculas específica para su RDBMS:

SELECT username, create_date FROM your_table 
    WHERE UPPER(username) IN 
    (SELECT UPPER(username) FROM your_table GROUP BY UPPER(username) HAVING COUNT(*) > 1) 
ORDER BY username, create_date 
+0

Si es para MYSQL, el UPPER no es necesario e incluso puede hacer que la consulta sea innecesariamente lenta. –

+0

Sí, eso es cierto (y cierto para varios otros RDBMS también). Voy a modificar la respuesta para reflejar eso. –

+0

OK +1 para la actualización. –

0

Use ToLower() o una función equivalente en su SELECT, y ordene por esa columna.

+0

Eso incluirá nombres de usuario que no sufren el problema de entradas múltiples. –

0

En MySQL, un caso sensible compare se realiza mediante una intercalación binaria. Por lo que podría unirse a la tabla de la misma, en busca de filas en las que el caso comparar sensible es diferente del caso insensible comparar:

select * 
from YourTable t1 
inner join YourTable t2 
on t1.name <> t2.name collate latin1_bin 
and t1.name = t2.name 
1

intentar algo como esto

SELECT UserName, CreatedDate 
FROM User 
WHERE LOWER(TRIM(UserName)) IN 
(
SELECT LOWER(TRIM(UserName)) 
FROM User 
GROUP BY LOWER(TRIM(UserName)) 
HAVING count(*) > 1 
) 
+0

Opps, veo que Larry publicó lo mismo primero –

0
SELECT UserName, CreatedDate 
FROM YourTable 
WHERE UserName COLLATE UTF8_BIN != LOWER(UserName COLLATE UTF8_BIN) 
GROUP BY UserName, CreatedDate 
HAVING COUNT(*) > 1 
+0

** De la cola de revisión **: Puedo solicitarle que agregue algo de contexto alrededor de su código fuente. Las respuestas de solo código son difíciles de entender. Ayudará al solicitante y a los lectores futuros tanto si puede agregar más información en su publicación. – RBT

Cuestiones relacionadas