Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

5 maneiras de retornar linhas que contêm letras minúsculas no SQL Server


Se você precisar encontrar linhas que contenham letras minúsculas no SQL Server, tente uma das seguintes opções.

Dados de amostra


Suponha que temos uma tabela com os seguintes dados:
SELECT c1 FROM t1;

Resultado:
+----------------+
| c1             |
|----------------|
| CAFÉ           |
| Café           |
| café           |
| 1café          |
| eCafé          |
| James Bond 007 |
| JB 007         |
| 007            |
| NULL           |
|                |
| É              |
| É 123          |
| é              |
| é 123          |
| ø              |
| Ø              |
+----------------+

Podemos usar os seguintes métodos para retornar as linhas que contêm letras minúsculas.

Opção 1:Compare com o UPPER() Cadeia


Podemos usar o UPPER() função para comparar o valor original com seu equivalente em maiúsculas:
SELECT * FROM t1
WHERE UPPER(c1) COLLATE Latin1_General_CS_AS <> c1;

Resultado:
+----------------+
| c1             |
|----------------|
| Café           |
| café           |
| 1café          |
| eCafé          |
| James Bond 007 |
| é              |
| é 123          |
| ø              |
+----------------+

Usando o diferente de (<> ) operador (você pode usar alternativamente != em vez de <> se preferir), apenas retornamos as linhas que são diferentes de seus equivalentes em maiúsculas. A razão pela qual fazemos isso é porque, se um valor é o mesmo que seu equivalente em maiúsculas, então já era em maiúsculas (e não queremos devolvê-lo).

Também usamos COLLATE Latin1_General_CS_AS para especificar explicitamente um agrupamento que diferencia maiúsculas de minúsculas (e diferencia acentos). Sem isso, você pode obter resultados inesperados, dependendo do agrupamento usado em seu sistema.

Opção 2:comparar com os caracteres reais


Alternativamente, podemos usar o LIKE operador e especifique os caracteres minúsculos reais que queremos corresponder:
SELECT * FROM t1
WHERE c1 LIKE '%[abcdefghijklmnopqrstuvwxyz]%'
COLLATE Latin1_General_CS_AS;

Resultado:
+----------------+
| c1             |
|----------------|
| Café           |
| café           |
| 1café          |
| eCafé          |
| James Bond 007 |
+----------------+

Nesse caso, menos linhas são retornadas do que no exemplo anterior. Isso ocorre porque eu não especifiquei caracteres como é e ø , que foram retornados no exemplo anterior. Embora uma linha contenha é , essa linha só foi retornada porque também contém outros caracteres minúsculos que correspondem.

Portanto, este exemplo é mais limitado que o anterior, mas fornece mais controle sobre os caracteres que você deseja corresponder.

Opção 3:comparar com um intervalo de caracteres


Alternativamente, podemos especificar o intervalo de caracteres que queremos corresponder:
SELECT * FROM t1
WHERE c1 LIKE '%[a-z]%'
COLLATE Latin1_General_100_BIN2;

Resultado:
+----------------+
| c1             |
|----------------|
| Café           |
| café           |
| 1café          |
| eCafé          |
| James Bond 007 |
+----------------+

Nesse caso, usei um agrupamento binário (Latin1_General_100_BIN2 ). Eu fiz isso porque os agrupamentos binários classificam cada caso separadamente (assim:AB....YZ...ab...yz ).

Outros agrupamentos tendem a misturar as letras maiúsculas e minúsculas (assim:AaBb...YyZz ), que, portanto, corresponderia a caracteres maiúsculos e minúsculos.

Opção 4:encontre a primeira instância de um caractere minúsculo


Outra maneira de fazer isso é usar o PATINDEX() função:
SELECT * FROM t1
WHERE PATINDEX('%[abcdefghijklmnopqrstuvwxyz]%', c1
COLLATE Latin1_General_CS_AS) > 0;

Resultado:
+----------------+
| c1             |
|----------------|
| Café           |
| café           |
| 1café          |
| eCafé          |
| James Bond 007 |
+----------------+

Neste exemplo, especificamos os caracteres exatos que queremos corresponder e, portanto, não obtivemos as linhas com caracteres como é e ø (diferente daquele que também contém outros caracteres que foram correspondidos).

Um benefício desta técnica é que podemos usá-la para ignorar o primeiro caractere (ou número especificado de caracteres) se assim o desejarmos:
SELECT * FROM t1
WHERE PATINDEX('%[abcdefghijklmnopqrstuvwxyz]%', c1
COLLATE Latin1_General_CS_AS) > 1;

Resultado:
+----------------+
| c1             |
|----------------|
| Café           |
| 1café          |
| James Bond 007 |
+----------------+

Portanto, podemos retornar todas as linhas que contêm caracteres minúsculos, mas onde o primeiro caractere não é minúsculo.

Isso ocorre porque PATINDEX() retorna a posição inicial da primeira ocorrência do padrão (no nosso caso, o padrão é uma lista de caracteres minúsculos). Se a posição inicial da primeira ocorrência for maior que 1, o primeiro caractere não estará em nossa lista de caracteres minúsculos.

Embora essa técnica possa ser usada para ignorar o primeiro caractere sendo maiúsculo, não exclui que o primeiro caractere possa ser outro caractere, como um número. Podemos ver isso na segunda linha, que contém 1café .

Opção 5:encontrar a primeira instância com base em um intervalo


Também podemos usar PATINDEX() com um intervalo:
SELECT * FROM t1
WHERE PATINDEX('%[a-z]%', c1
COLLATE Latin1_General_100_BIN2) > 1;

Resultado:
+----------------+
| c1             |
|----------------|
| Café           |
| 1café          |
| James Bond 007 |
+----------------+

Usei novamente um agrupamento binário (como no outro exemplo de intervalo).