Llevaba tiempo detrás de este asunto, pero las diferentes obligaciones molineras me impedían centrarme en el tema, pero ha llegado el mes de agosto y en vez de tumbarme al sol en la piscina, con el correspondiente protector solar para evitar problemas mayores,
En el caso concreto de MySQL y seguramente de otras estructuras de bases de datos, tenemos un problema concreto con las búsquedas. Un problema o una ventaja. Cuando hacemos una consulta para un campo de texto el sistema considera iguales letras mayúsculas y minúsculas así como vocales con tilde como vocales sin tilde. Esto a veces es una ventaja, ya que no nos importa que una palabra tenga las tildes correctas o que tenga las letras mayúsculas igual que la muestra, pero en otros casos, no queremos que eso sea así.
En nuestro caso particular, trabajamos con palabras, diccionarios y recursos para lengua, nos interesa diferenciar entre palabras con la tilde en diferente posición y no nos resultan iguales palabras como médico, medico y medicó. Para ayudarnos a resolver el tema está el parámetro COLLATE y el conjunto de caracteres (charset) utf8_bin.
Así si ejecutamos la instrucción SELECT de esta forma:
SELECT * FROM tabla
WHERE palabra = ‘medico’;
El sistema seleccionara filas que contengan tanto la palabra ‘medico’, médico’ o ‘medicó’. También obtendremos ‘Medico’ o ‘MEDICÓ’. Sin embargo si añadís ‘COLLATE ‘ utf8_bin a la comparación, el resultado será sólo los registros que tengáis exactamente los caracteres con los que estáis comparando. Este sería el formato a aplicar:
SELECT * FROM tabla
WHERE palabra = ‘medico’ COLLATE utf8_bin;
Podría darse el caso de que nos interese diferenciar entre vocales con tilde y sin tilde, pero si importar las mayúsculas. En este caso la solución pasa por mantener el COLLATE pero convertir los valores a comparar en mayúsculas usando la función UPPER() o en minúsculas LOWER(). Así ahora tendríamos:
SELECT * FROM tabla
WHERE LOWER(palabra) = ‘medico’ COLLATE utf8_bin;
Esto es todo. Espero que os haya servido. Agradezco la información a PHP’S Blog y en particular a su autor, Agustín Villalba Casás, que en su entrada “distinguir mayúsculas y minúsculas en MySQL” han servido de inspiración para esta entrada.
Aprovecho para recordaos el formato de las entradas SELECT según el manual de SQL:
SELECT [ALL | DISTINCT | DISTINCTROW ] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]select_expr
, ... [INTO OUTFILE 'file_name
'export_options
| INTO DUMPFILE 'file_name
'] [FROMtable_references
[WHEREwhere_definition
] [GROUP BY {col_name
|expr
|position
} [ASC | DESC], ... [WITH ROLLUP]] [HAVINGwhere_definition
] [ORDER BY {col_name
|expr
|position
} [ASC | DESC] , ...] [LIMIT {[offset
,]row_count
|row_count
OFFSEToffset
}] [PROCEDUREprocedure_name
(argument_list
)] [FOR UPDATE | LOCK IN SHARE MODE]]
y las funciones, LOWER(str
)
Retorna la cadena str
con todos los caracteres cambiados a minúsculas según el mapeo del conjunto de caracteres actual (por defecto es ISO-8859-1 Latin1).
mysql> SELECT LOWER('QUADRATICALLY'); -> 'quadratically'
y UPPER(str
)
Retorna la cadena str
con todos los caracteres cambiados a mayúsculas según el mapeo del conjunto de caracteres actual (por defecto es ISO-8859-1 Latin1).
mysql> SELECT UPPER('quadratically'); -> 'QUADRATICALLY'