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

5 maneiras de encontrar linhas que contêm letras maiúsculas no SQL Server


Abaixo estão cinco opções para retornar linhas que contêm letras maiúsculas no SQL Server.

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 maiúsculas.

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


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

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

Usando o diferente de (<> ) (você pode usar alternativamente != em vez de <> se preferir), apenas retornamos as linhas que são diferentes de seus equivalentes em minúsculas. A razão pela qual fazemos isso é porque, se um valor é o mesmo que seu equivalente em minúsculas, então já estava em minú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


Outra opção é usar o LIKE operador e especifique os caracteres maiúsculos reais que queremos corresponder:
SELECT c1 FROM t1
WHERE c1 LIKE '%[ABCDEFGHIJKLMNOPQRSTUVWXYZ]%'
COLLATE Latin1_General_CS_AS;

Resultado:
+----------------+
| c1             |
|----------------|
| CAFÉ           |
| Café           |
| eCafé          |
| James Bond 007 |
| JB 007         |
+----------------+

Nesse caso, menos linhas são retornadas do que no exemplo anterior. Isso ocorre porque não especifiquei caracteres como É e Ø , que foram retornados no exemplo anterior. Nosso resultado contém É mas essa linha só foi retornada porque também contém outros caracteres maiúsculos que fazem partida.

Portanto, essa opção é mais limitada que a 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é           |
| eCafé          |
| James Bond 007 |
| JB 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 maiú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é           |
| eCafé          |
| James Bond 007 |
| JB 007         |
+----------------+

Neste exemplo, especificamos os caracteres exatos que queremos corresponder e, portanto, não obtivemos as linhas com os caracteres like É 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:
Time: 0.472s
+-------+
| c1    |
|-------|
| eCafé |
+-------+

Portanto, podemos retornar todas as linhas que contêm caracteres maiúsculos, mas onde o primeiro caractere não é maiú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 maiú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 maiúsculos.

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    |
|-------|
| eCafé |
+-------+

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