Hvis du har brug for at finde rækker, der indeholder små bogstaver i SQL Server, kan du prøve en af følgende muligheder.
Eksempel på data
Antag, at vi har en tabel med følgende data:
SELECT c1 FROM t1;
Resultat:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | café | | 1café | | eCafé | | James Bond 007 | | JB 007 | | 007 | | NULL | | | | É | | É 123 | | é | | é 123 | | ø | | Ø | +----------------+
Vi kan bruge følgende metoder til at returnere de rækker, der indeholder små bogstaver.
Mulighed 1:Sammenlign med UPPER()
Streng
Vi kan bruge UPPER()
funktion til at sammenligne den oprindelige værdi med dens ækvivalent med store bogstaver:
SELECT * FROM t1
WHERE UPPER(c1) COLLATE Latin1_General_CS_AS <> c1;
Resultat:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | | é | | é 123 | | ø | +----------------+
Ved at bruge ikke lig med (<> ) operator (du kan alternativt bruge
!=
i stedet for <> hvis du foretrækker det), returnerer vi kun de rækker, der er forskellige fra deres store bogstaver. Grunden til, at vi gør dette, er, at hvis en værdi er den samme som dens store bogstaver, så var den allerede store bogstaver til at begynde med (og vi ønsker ikke at returnere den).
Vi bruger også COLLATE Latin1_General_CS_AS
for eksplicit at angive en versalfølsom (og accentfølsom) sammenstilling. Uden dette kan du få uventede resultater, afhængigt af den sortering, der bruges på dit system.
Mulighed 2:Sammenlign med de faktiske tegn
Vi kan alternativt bruge LIKE
operator, og angiv de faktiske små bogstaver, som vi ønsker at matche:
SELECT * FROM t1
WHERE c1 LIKE '%[abcdefghijklmnopqrstuvwxyz]%'
COLLATE Latin1_General_CS_AS;
Resultat:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
I dette tilfælde returneres færre rækker end i det foregående eksempel. Dette skyldes, at jeg ikke specificerede tegn som é
og ø
, som blev returneret i det foregående eksempel. Selvom en række indeholder é
, den række blev kun returneret, fordi den også indeholder andre små bogstaver, der matcher.
Derfor er dette eksempel mere begrænset end det foregående, men det giver dig mere kontrol over de karakterer, du vil matche.
Mulighed 3:Sammenlign med en række tegn
Vi kan alternativt angive rækken af tegn, vi ønsker at matche:
SELECT * FROM t1
WHERE c1 LIKE '%[a-z]%'
COLLATE Latin1_General_100_BIN2;
Resultat:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
I dette tilfælde brugte jeg en binær sortering (Latin1_General_100_BIN2
). Jeg gjorde dette, fordi binære sammenstillinger sorterer hvert tilfælde separat (som dette:AB...YZ...ab...yz
).
Andre sammenstillinger har en tendens til at blande store og små bogstaver (som dette:AaBb...YyZz
), som derfor ville matche både store og små bogstaver.
Mulighed 4:Find den første forekomst af et lille tegn
En anden måde at gøre det på er at bruge PATINDEX()
funktion:
SELECT * FROM t1
WHERE PATINDEX('%[abcdefghijklmnopqrstuvwxyz]%', c1
COLLATE Latin1_General_CS_AS) > 0;
Resultat:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
I dette eksempel specificerer vi de nøjagtige tegn, som vi ønsker at matche, og så i dette tilfælde fik vi ikke rækkerne med tegn som é
og ø
(andre end den, der også indeholder andre tegn, der blev matchet).
En fordel ved denne teknik er, at vi kan bruge den til at ignorere det første tegn (eller det specificerede antal tegn), hvis vi ønsker det:
SELECT * FROM t1
WHERE PATINDEX('%[abcdefghijklmnopqrstuvwxyz]%', c1
COLLATE Latin1_General_CS_AS) > 1;
Resultat:
+----------------+ | c1 | |----------------| | Café | | 1café | | James Bond 007 | +----------------+
Derfor kan vi returnere alle rækker, der indeholder små bogstaver, men hvor det første tegn ikke er småt.
Dette er fordi PATINDEX()
returnerer startpositionen for den første forekomst af mønsteret (i vores tilfælde er mønsteret en liste med små bogstaver). Hvis startpositionen for den første forekomst er større end 1, er det første tegn ikke på vores liste over små bogstaver.
Selvom denne teknik kunne bruges til at ignorere, at det første tegn er stort, udelukker det ikke, at det første tegn kan være et andet tegn, såsom et tal. Vi kan se dette i den anden række, som indeholder 1café
.
Mulighed 5:Find den første instans baseret på et område
Vi kan også bruge PATINDEX()
med et interval:
SELECT * FROM t1
WHERE PATINDEX('%[a-z]%', c1
COLLATE Latin1_General_100_BIN2) > 1;
Resultat:
+----------------+ | c1 | |----------------| | Café | | 1café | | James Bond 007 | +----------------+
Jeg brugte igen en binær sortering (som med det andet områdeeksempel).