Se hai bisogno di trovare righe che contengono lettere minuscole in SQL Server, puoi provare una delle seguenti opzioni.
Dati di esempio
Supponiamo di avere una tabella con i seguenti dati:
SELECT c1 FROM t1;
Risultato:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | café | | 1café | | eCafé | | James Bond 007 | | JB 007 | | 007 | | NULL | | | | É | | É 123 | | é | | é 123 | | ø | | Ø | +----------------+
Possiamo usare i seguenti metodi per restituire le righe che contengono lettere minuscole.
Opzione 1:confronta con UPPER()
Stringa
Possiamo usare UPPER()
funzione per confrontare il valore originale con il suo equivalente maiuscolo:
SELECT * FROM t1
WHERE UPPER(c1) COLLATE Latin1_General_CS_AS <> c1;
Risultato:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | | é | | é 123 | | ø | +----------------+
Utilizzando il diverso a (<>
) operatore (puoi in alternativa usare !=
invece di <>
se preferisci), restituiamo solo quelle righe che sono diverse dai loro equivalenti maiuscoli. Il motivo per cui lo facciamo è perché, se un valore è uguale al suo equivalente maiuscolo, all'inizio era già maiuscolo (e non vogliamo restituirlo).
Usiamo anche COLLATE Latin1_General_CS_AS
per specificare in modo esplicito un confronto con distinzione tra maiuscole e minuscole (e con accento). Senza questo, potresti ottenere risultati imprevisti, a seconda delle regole di confronto utilizzate sul tuo sistema.
Opzione 2:confronta con i caratteri reali
In alternativa possiamo usare il LIKE
operatore e specificare i caratteri minuscoli effettivi che vogliamo far corrispondere:
SELECT * FROM t1
WHERE c1 LIKE '%[abcdefghijklmnopqrstuvwxyz]%'
COLLATE Latin1_General_CS_AS;
Risultato:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
In questo caso, vengono restituite meno righe rispetto all'esempio precedente. Questo perché non ho specificato caratteri come é
e ø
, restituiti nell'esempio precedente. Sebbene una riga contenga é
, quella riga è stata restituita solo perché contiene anche altri caratteri minuscoli che corrispondono.
Pertanto, questo esempio è più limitato del precedente, ma ti offre un maggiore controllo sui caratteri che desideri abbinare.
Opzione 3:confronta con un intervallo di caratteri
Possiamo in alternativa specificare l'intervallo di caratteri che vogliamo abbinare:
SELECT * FROM t1
WHERE c1 LIKE '%[a-z]%'
COLLATE Latin1_General_100_BIN2;
Risultato:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
In questo caso, ho usato un confronto binario (Latin1_General_100_BIN2
). L'ho fatto perché le regole di confronto binarie ordinano ogni caso separatamente (come questo:AB....YZ...ab...yz
).
Altre regole di confronto tendono a mescolare le lettere maiuscole e minuscole (come questo:AaBb...YyZz
), che quindi corrisponderebbe sia ai caratteri maiuscoli che a quelli minuscoli.
Opzione 4:trova la prima istanza di un carattere minuscolo
Un altro modo per farlo è usare PATINDEX()
funzione:
SELECT * FROM t1
WHERE PATINDEX('%[abcdefghijklmnopqrstuvwxyz]%', c1
COLLATE Latin1_General_CS_AS) > 0;
Risultato:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
In questo esempio, specifichiamo i caratteri esatti che vogliamo far corrispondere, quindi in questo caso non abbiamo ottenuto le righe con caratteri come é
e ø
(diverso da quello che contiene anche altri caratteri che sono stati abbinati).
Un vantaggio di questa tecnica è che possiamo usarla per ignorare il primo carattere (o il numero specificato di caratteri) se lo desideriamo:
SELECT * FROM t1
WHERE PATINDEX('%[abcdefghijklmnopqrstuvwxyz]%', c1
COLLATE Latin1_General_CS_AS) > 1;
Risultato:
+----------------+ | c1 | |----------------| | Café | | 1café | | James Bond 007 | +----------------+
Pertanto, possiamo restituire tutte le righe che contengono caratteri minuscoli, ma in cui il primo carattere non è minuscolo.
Questo perché PATINDEX()
restituisce la posizione iniziale della prima occorrenza del pattern (nel nostro caso, il pattern è un elenco di caratteri minuscoli). Se la posizione iniziale della prima occorrenza è maggiore di 1, il primo carattere non è nel nostro elenco di caratteri minuscoli.
Sebbene questa tecnica possa essere utilizzata per ignorare che il primo carattere sia maiuscolo, non esclude che il primo carattere possa essere un altro carattere, ad esempio un numero. Possiamo vederlo nella seconda riga, che contiene 1café
.
Opzione 5:trova la prima istanza in base a un intervallo
Possiamo anche usare PATINDEX()
con un intervallo:
SELECT * FROM t1
WHERE PATINDEX('%[a-z]%', c1
COLLATE Latin1_General_100_BIN2) > 1;
Risultato:
+----------------+ | c1 | |----------------| | Café | | 1café | | James Bond 007 | +----------------+
Ho usato di nuovo un confronto binario (come con l'altro esempio di intervallo).