Pokud potřebujete na SQL Serveru najít řádky, které obsahují malá písmena, můžete zkusit jednu z následujících možností.
Ukázková data
Předpokládejme, že máme tabulku s následujícími údaji:
SELECT c1 FROM t1;
Výsledek:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | café | | 1café | | eCafé | | James Bond 007 | | JB 007 | | 007 | | NULL | | | | É | | É 123 | | é | | é 123 | | ø | | Ø | +----------------+
K vrácení řádků, které obsahují malá písmena, můžeme použít následující metody.
Možnost 1:Porovnejte s UPPER()
Řetězec
Můžeme použít UPPER()
funkce pro porovnání původní hodnoty s jejím ekvivalentem velkým písmenem:
SELECT * FROM t1
WHERE UPPER(c1) COLLATE Latin1_General_CS_AS <> c1;
Výsledek:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | | é | | é 123 | | ø | +----------------+
Pomocí nerovná se (<>
) operátor (můžete také použít !=
místo <>
pokud chcete), vracíme pouze ty řádky, které se liší od jejich ekvivalentů velkými písmeny. Důvod, proč to děláme, je ten, že pokud je hodnota stejná jako její ekvivalent velkými písmeny, pak již byla na začátku velká (a my ji nechceme vracet).
Používáme také COLLATE Latin1_General_CS_AS
explicitně specifikovat řazení rozlišující malá a velká písmena (a zvýraznění). Bez toho byste mohli získat neočekávané výsledky v závislosti na řazení používaném ve vašem systému.
Možnost 2:Porovnejte se skutečnými postavami
Alternativně můžeme použít LIKE
operátor a zadejte skutečná malá písmena, která chceme porovnat:
SELECT * FROM t1
WHERE c1 LIKE '%[abcdefghijklmnopqrstuvwxyz]%'
COLLATE Latin1_General_CS_AS;
Výsledek:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
V tomto případě je vráceno méně řádků než v předchozím příkladu. Je to proto, že jsem nespecifikoval znaky jako é
a ø
, které byly vráceny v předchozím příkladu. Ačkoli jeden řádek obsahuje é
, tento řádek byl vrácen pouze proto, že obsahuje i jiná malá písmena, která se shodují.
Proto je tento příklad omezenější než předchozí, ale poskytuje vám větší kontrolu nad postavami, které chcete porovnat.
Možnost 3:Porovnejte s řadou znaků
Alternativně můžeme zadat rozsah znaků, které chceme porovnat:
SELECT * FROM t1
WHERE c1 LIKE '%[a-z]%'
COLLATE Latin1_General_100_BIN2;
Výsledek:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
V tomto případě jsem použil binární řazení (Latin1_General_100_BIN2
). Udělal jsem to, protože binární porovnávání třídí každý případ zvlášť (takto:AB....YZ...ab...yz
).
Jiná řazení mají tendenci prolínat velká a malá písmena (jako toto:AaBb...YyZz
), které by tedy odpovídaly jak velkým, tak malým písmenům.
Možnost 4:Najděte první instanci malého znaku
Dalším způsobem, jak to udělat, je použít PATINDEX()
funkce:
SELECT * FROM t1
WHERE PATINDEX('%[abcdefghijklmnopqrstuvwxyz]%', c1
COLLATE Latin1_General_CS_AS) > 0;
Výsledek:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
V tomto příkladu zadáváme přesné znaky, které chceme porovnat, a proto jsme v tomto případě nezískali řádky s znaky jako é
a ø
(jiný než ten, který obsahuje i jiné znaky, které byly shodné).
Jednou z výhod této techniky je, že ji můžeme použít k ignorování prvního znaku (nebo zadaného počtu znaků), pokud si to přejeme:
SELECT * FROM t1
WHERE PATINDEX('%[abcdefghijklmnopqrstuvwxyz]%', c1
COLLATE Latin1_General_CS_AS) > 1;
Výsledek:
+----------------+ | c1 | |----------------| | Café | | 1café | | James Bond 007 | +----------------+
Můžeme tedy vrátit všechny řádky, které obsahují malá písmena, ale kde první znak není malé.
Důvodem je PATINDEX()
vrací počáteční pozici prvního výskytu vzoru (v našem případě je vzorem seznam malých písmen). Pokud je počáteční pozice prvního výskytu větší než 1, pak první znak není v našem seznamu malých písmen.
I když lze tuto techniku použít k ignorování prvního znaku, který je velkým písmenem, nevylučuje, že prvním znakem může být jiný znak, například číslo. Můžeme to vidět na druhém řádku, který obsahuje 1café
.
Možnost 5:Najděte první instanci na základě rozsahu
Můžeme také použít PATINDEX()
s rozsahem:
SELECT * FROM t1
WHERE PATINDEX('%[a-z]%', c1
COLLATE Latin1_General_100_BIN2) > 1;
Výsledek:
+----------------+ | c1 | |----------------| | Café | | 1café | | James Bond 007 | +----------------+
Znovu jsem použil binární řazení (jako v příkladu jiného rozsahu).