sql >> Database >  >> RDS >> Sqlserver

5 manieren om rijen met hoofdletters te vinden in SQL Server

Hieronder staan ​​vijf opties voor het retourneren van rijen die hoofdletters bevatten in SQL Server.

Voorbeeldgegevens

Stel dat we een tabel hebben met de volgende gegevens:

SELECT c1 FROM t1;

Resultaat:

+----------------+
| c1             |
|----------------|
| CAFÉ           |
| Café           |
| café           |
| 1café          |
| eCafé          |
| James Bond 007 |
| JB 007         |
| 007            |
| NULL           |
|                |
| É              |
| É 123          |
| é              |
| é 123          |
| ø              |
| Ø              |
+----------------+

We kunnen de volgende methoden gebruiken om de rijen die hoofdletters bevatten te retourneren.

Optie 1:Vergelijk met de LOWER() Tekenreeks

We kunnen de LOWER() . gebruiken functie om de oorspronkelijke waarde te vergelijken met het equivalent in kleine letters:

SELECT c1 FROM t1
WHERE LOWER(c1) COLLATE Latin1_General_CS_AS <> c1;

Resultaat:

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

Door het gebruik van de niet gelijk aan (<> ) operator (u kunt ook != gebruiken in plaats van <> als je dat liever hebt), retourneren we alleen die rijen die verschillen van hun equivalenten in kleine letters. De reden dat we dit doen is omdat, als een waarde hetzelfde is als het equivalent in kleine letters, het al in kleine letters was (en we willen het niet teruggeven).

We gebruiken ook COLLATE Latin1_General_CS_AS om expliciet een hoofdlettergevoelige (en accentgevoelige) sortering op te geven. Zonder dit kunt u onverwachte resultaten krijgen, afhankelijk van de sortering die op uw systeem wordt gebruikt.

Optie 2:Vergelijk met de werkelijke tekens

Een andere optie is om de LIKE . te gebruiken operator en specificeer de eigenlijke hoofdletters die we willen matchen:

SELECT c1 FROM t1
WHERE c1 LIKE '%[ABCDEFGHIJKLMNOPQRSTUVWXYZ]%'
COLLATE Latin1_General_CS_AS;

Resultaat:

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

In dit geval worden er minder rijen geretourneerd dan in het vorige voorbeeld. Dit komt omdat ik geen tekens zoals É . heb gespecificeerd en Ø , die in het vorige voorbeeld zijn geretourneerd. Ons resultaat bevat É maar die rij werd alleen geretourneerd omdat deze ook andere hoofdletters bevat die doen wedstrijd.

Daarom is deze optie beperkter dan de vorige, maar het geeft je wel meer controle over de karakters die je wilt matchen.

Optie 3:vergelijken met een reeks tekens

We kunnen ook het bereik van tekens specificeren dat we willen matchen:

SELECT * FROM t1
WHERE c1 LIKE '%[A-Z]%'
COLLATE Latin1_General_100_BIN2;

Resultaat:

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

In dit geval heb ik een binaire sortering gebruikt (Latin1_General_100_BIN2 ). Ik deed dit omdat binaire sorteringen elk geval apart sorteren (zoals dit:AB....YZ...ab...yz ).

Andere sorteringen hebben de neiging om hoofdletters en kleine letters te vermengen (zoals deze:AaBb...YyZz ), wat dus overeen zou komen met zowel hoofdletters als kleine letters.

Optie 4:Zoek de eerste instantie van een hoofdletter

Een andere manier om dit te doen is door de PATINDEX() . te gebruiken functie:

SELECT * FROM t1
WHERE PATINDEX('%[ABCDEFGHIJKLMNOPQRSTUVWXYZ]%', c1
COLLATE Latin1_General_CS_AS) > 0;

Resultaat:

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

In dit voorbeeld specificeren we de exacte tekens die we willen matchen, en dus hebben we in dit geval de rijen met tekens like É en Ø (anders dan degene die ook andere tekens bevat die overeenkomen).

Een voordeel van deze techniek is dat we deze kunnen gebruiken om het eerste teken (of het opgegeven aantal tekens) te negeren als we dat willen:

SELECT * FROM t1
WHERE PATINDEX('%[ABCDEFGHIJKLMNOPQRSTUVWXYZ]%', c1
COLLATE Latin1_General_CS_AS) > 1;

Resultaat:

Time: 0.472s
+-------+
| c1    |
|-------|
| eCafé |
+-------+

Daarom kunnen we alle rijen retourneren die hoofdletters bevatten, maar waarvan het eerste teken geen hoofdletters is.

Dit komt omdat PATINDEX() retourneert de startpositie van het eerste voorkomen van het patroon (in ons geval is het patroon een lijst met hoofdletters). Als de startpositie van het eerste voorkomen groter is dan 1, dan staat het eerste teken niet in onze lijst met hoofdletters.

Optie 5:vind het eerste exemplaar op basis van een bereik

We kunnen ook PATINDEX() . gebruiken met een bereik:

SELECT * FROM t1
WHERE PATINDEX('%[A-Z]%', c1
COLLATE Latin1_General_100_BIN2) > 1;

Resultaat:

+-------+
| c1    |
|-------|
| eCafé |
+-------+

Ik heb opnieuw een binaire sortering gebruikt (zoals bij het andere bereikvoorbeeld).


  1. Informatiesystemen, gegevens en informatie

  2. Structured Query Language – Het belang van het leren van SQL

  3. VLDB's in de 20-tieners:je hebt een grotere nodig ...

  4. Grondbeginselen van tabeluitdrukkingen, deel 11 - Aanzichten, overwegingen bij wijzigingen