Di seguito sono elencate cinque opzioni per la restituzione di righe che contengono lettere maiuscole in SQL Server.
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 maiuscole.
Opzione 1:confronta con LOWER()
Stringa
Possiamo usare il LOWER()
funzione per confrontare il valore originale con il suo equivalente minuscolo:
SELECT c1 FROM t1
WHERE LOWER(c1) COLLATE Latin1_General_CS_AS <> c1;
Risultato:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | eCafé | | James Bond 007 | | JB 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 minuscoli. Il motivo per cui lo facciamo è perché, se un valore è uguale al suo equivalente minuscolo, all'inizio era già minuscolo (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
Un'altra opzione è usare il LIKE
operatore e specificare i caratteri maiuscoli effettivi che vogliamo abbinare:
SELECT c1 FROM t1
WHERE c1 LIKE '%[ABCDEFGHIJKLMNOPQRSTUVWXYZ]%'
COLLATE Latin1_General_CS_AS;
Risultato:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | eCafé | | James Bond 007 | | JB 007 | +----------------+
In questo caso, vengono restituite meno righe rispetto all'esempio precedente. Questo perché non ho specificato caratteri come É
e Ø
, restituiti nell'esempio precedente. Il nostro risultato contiene É
ma quella riga è stata restituita solo perché contiene anche altri caratteri maiuscoli che fa corrispondenza.
Pertanto, questa opzione è più limitata della precedente, ma ti offre un maggiore controllo sui personaggi 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é | | eCafé | | James Bond 007 | | JB 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 questa:AaBb...YyZz
), che quindi corrisponderebbe sia ai caratteri maiuscoli che a quelli minuscoli.
Opzione 4:trova la prima istanza di un carattere maiuscolo
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é | | eCafé | | James Bond 007 | | JB 007 | +----------------+
In questo esempio, specifichiamo i caratteri esatti che vogliamo far corrispondere, quindi in questo caso non abbiamo ottenuto le righe con i caratteri like É
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:
Time: 0.472s +-------+ | c1 | |-------| | eCafé | +-------+
Pertanto, possiamo restituire tutte le righe che contengono caratteri maiuscoli, ma in cui il primo carattere non è maiuscolo.
Questo perché PATINDEX()
restituisce la posizione iniziale della prima occorrenza del pattern (nel nostro caso, il pattern è un elenco di caratteri maiuscoli). Se la posizione iniziale della prima occorrenza è maggiore di 1, il primo carattere non è nel nostro elenco di caratteri maiuscoli.
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 | |-------| | eCafé | +-------+
Ho usato di nuovo un confronto binario (come con l'altro esempio di intervallo).