Si necesita encontrar filas que contengan letras minúsculas en SQL Server, puede probar una de las siguientes opciones.
Datos de muestra
Supongamos que tenemos una tabla con los siguientes datos:
SELECT c1 FROM t1;
Resultado:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | café | | 1café | | eCafé | | James Bond 007 | | JB 007 | | 007 | | NULL | | | | É | | É 123 | | é | | é 123 | | ø | | Ø | +----------------+
Podemos usar los siguientes métodos para devolver las filas que contienen letras minúsculas.
Opción 1:comparar con UPPER()
Cadena
Podemos usar UPPER()
función para comparar el valor original con su equivalente en mayúsculas:
SELECT * FROM t1
WHERE UPPER(c1) COLLATE Latin1_General_CS_AS <> c1;
Resultado:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | | é | | é 123 | | ø | +----------------+
Usando el no igual a (<>
) operador (también puede usar !=
en lugar de <>
si lo prefiere), solo devolvemos aquellas filas que son diferentes a sus equivalentes en mayúsculas. La razón por la que hacemos esto es porque, si un valor es igual a su equivalente en mayúsculas, para empezar ya estaba en mayúsculas (y no queremos devolverlo).
También usamos COLLATE Latin1_General_CS_AS
para especificar explícitamente una intercalación que distingue mayúsculas de minúsculas (y acentos). Sin esto, podría obtener resultados inesperados, según la intercalación que se utilice en su sistema.
Opción 2:comparar con los caracteres reales
Alternativamente podemos usar el LIKE
y especifique los caracteres en minúscula reales que queremos que coincidan:
SELECT * FROM t1
WHERE c1 LIKE '%[abcdefghijklmnopqrstuvwxyz]%'
COLLATE Latin1_General_CS_AS;
Resultado:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
En este caso, se devuelven menos filas que en el ejemplo anterior. Esto se debe a que no especifiqué caracteres como é
y ø
, que se devolvieron en el ejemplo anterior. Aunque una fila contiene é
, esa fila solo se devolvió porque también contiene otros caracteres en minúsculas que sí coinciden.
Por lo tanto, este ejemplo es más limitado que el anterior, pero le brinda más control sobre los caracteres que desea hacer coincidir.
Opción 3:comparar con un rango de caracteres
Alternativamente, podemos especificar el rango de caracteres que queremos hacer coincidir:
SELECT * FROM t1
WHERE c1 LIKE '%[a-z]%'
COLLATE Latin1_General_100_BIN2;
Resultado:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
En este caso, utilicé una intercalación binaria (Latin1_General_100_BIN2
). Hice esto porque las intercalaciones binarias clasifican cada caso por separado (así:AB....YZ...ab...yz
).
Otras intercalaciones tienden a entremezclar las letras mayúsculas y minúsculas (como esta:AaBb...YyZz
), que por lo tanto coincidiría con caracteres en mayúsculas y minúsculas.
Opción 4:encontrar la primera instancia de un carácter en minúsculas
Otra forma de hacerlo es usar el PATINDEX()
función:
SELECT * FROM t1
WHERE PATINDEX('%[abcdefghijklmnopqrstuvwxyz]%', c1
COLLATE Latin1_General_CS_AS) > 0;
Resultado:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
En este ejemplo, especificamos los caracteres exactos que queremos hacer coincidir, por lo que en este caso no obtuvimos las filas con caracteres como é
y ø
(que no sea el que también contiene otros caracteres que coincidieron).
Un beneficio de esta técnica es que podemos usarla para ignorar el primer carácter (o un número específico de caracteres) si así lo deseamos:
SELECT * FROM t1
WHERE PATINDEX('%[abcdefghijklmnopqrstuvwxyz]%', c1
COLLATE Latin1_General_CS_AS) > 1;
Resultado:
+----------------+ | c1 | |----------------| | Café | | 1café | | James Bond 007 | +----------------+
Por lo tanto, podemos devolver todas las filas que contienen caracteres en minúsculas, pero donde el primer carácter no está en minúsculas.
Esto se debe a que PATINDEX()
devuelve la posición inicial de la primera aparición del patrón (en nuestro caso, el patrón es una lista de caracteres en minúsculas). Si la posición de inicio de la primera aparición es mayor que 1, entonces el primer carácter no está en nuestra lista de caracteres en minúsculas.
Si bien esta técnica podría usarse para ignorar que el primer carácter está en mayúsculas, no descarta que el primer carácter pueda ser otro carácter, como un número. Podemos ver esto en la segunda fila, que contiene 1café
.
Opción 5:encontrar la primera instancia basada en un rango
También podemos usar PATINDEX()
con un rango:
SELECT * FROM t1
WHERE PATINDEX('%[a-z]%', c1
COLLATE Latin1_General_100_BIN2) > 1;
Resultado:
+----------------+ | c1 | |----------------| | Café | | 1café | | James Bond 007 | +----------------+
Nuevamente usé una intercalación binaria (como con el otro ejemplo de rango).