2009-06-10 21 views

Antwort

385

Sie COLLATE NOCASE in Ihrem SELECT Abfrage verwenden können:..

SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE 

Zusätzlich können Sie in SQLite angeben, dass eine Spalte bei der Erstellung der Tabelle nicht zwischen Groß- und Kleinschreibung unterscheiden darf, indem Sie in der Spaltendefinition collate nocase angeben (die anderen Optionen sind binary (Standard) und rtrim; siehe here). Sie können collate nocase angeben, wenn Sie auch einen Index erstellen. Zum Beispiel:

 
create table Test 
(
    Text_Value text collate nocase 
); 

insert into Test values ('A'); 
insert into Test values ('b'); 
insert into Test values ('C'); 

create index Test_Text_Value_Index 
    on Test (Text_Value collate nocase); 

Expressions Test.Text_Value Beteiligung soll nun Fall unempfindlich sein. Zum Beispiel:

 
sqlite> select Text_Value from Test where Text_Value = 'B'; 
Text_Value  
---------------- 
b    

sqlite> select Text_Value from Test order by Text_Value; 
Text_Value  
---------------- 
A    
b    
C  

sqlite> select Text_Value from Test order by Text_Value desc; 
Text_Value  
---------------- 
C    
b    
A    

Der Optimiser kann möglicherweise auch den Index für die Groß- und Kleinschreibung Suche und die Anpassung an die Säule machen. Sie können prüfen, diese mit dem explain SQL-Befehl, z.B .:

 
sqlite> explain select Text_Value from Test where Text_Value = 'b'; 
addr    opcode   p1   p2   p3        
---------------- -------------- ---------- ---------- --------------------------------- 
0     Goto   0   16           
1     Integer   0   0            
2     OpenRead  1   3   keyinfo(1,NOCASE)     
3     SetNumColumns 1   2            
4     String8   0   0   b         
5     IsNull   -1   14           
6     MakeRecord  1   0   a         
7     MemStore  0   0            
8     MoveGe   1   14           
9     MemLoad   0   0            
10    IdxGE   1   14   +         
11    Column   1   0            
12    Callback  1   0            
13    Next   1   9            
14    Close   1   0            
15    Halt   0   0            
16    Transaction  0   0            
17    VerifyCookie 0   4            
18    Goto   0   1            
19    Noop   0   0            
+12

Nachdem ich (neu) die Tabelle mit 'COLLATE NOCASE' erstellt hatte, bemerkte ich, dass _much_ schneller war als die Abfrage WHERE name = 'jemand' COLLATE NOCASE. VIEL schneller (sechs bis zehnmal, grob?) – DefenestrationDay

+6

Laut der Dokumentation ist das Hinzufügen von 'COLLATE NOCASE' zum Index nicht erforderlich, wenn das Feld selbst diese Kollatierung bereits definiert hat: "[*] Die Standard-Sortierfolge ist die Sortierfolge definiert für diese Spalte in der CREATE TABLE-Anweisung. *] (http://www.sqlite.org/lang_createindex.html) " – Heinzi

+19

' COLLATE NOCASE "funktioniert nur mit ASCII-Text. Sobald Sie "FIANCÉ" oder "Voilà" in Ihren Spaltenwerten haben, wird es nicht mit "fiancé" oder "VOILA" übereinstimmen. Nach dem Aktivieren der ICU-Erweiterung wird ['LIKE' die Groß-/Kleinschreibung nicht beachtet] (http://www.sqlite.org/src/artifact?ci=trunk&filename=ext/icu/README.txt), also' 'FIANCÉ' LIKE ' Verlobte ist wahr, aber "VOILA" wie "Voilà" ist immer noch falsch. Und ICU + LIKE hat den Nachteil, den Index nicht zu benutzen, so dass es auf großen Tischen langsam sein kann. –

32

Dies ist auf SQLite nicht spezifisch, aber Sie tun können, nur

SELECT * FROM ... WHERE UPPER(name) = UPPER('someone') 
+2

Gibt es einen Leistungsverlust, wenn Sie dies tun? – quantity

+0

Der andere Teil des Leistungsbedenkens besteht darin, die übereinstimmenden Zeilen in der Tabelle zu finden. Unterstützt SQLite3 funktionsbasierte Indizes? Das Indizieren der Suchspalte oder des Ausdrucks (z. B. "UPPER (Name)") in einer solchen Situation ist normalerweise eine gute Idee. – cheduardo

+9

Passen Sie mit diesem auf, wie cheduardo andeutete, kann SQLite keinen Index für 'name' verwenden, wenn diese Abfrage ausgeführt wird. Die db-Engine muss alle Zeilen vollständig scannen, alle "name" -Felder in Großbuchstaben umwandeln und den Vergleich ausführen. –

37

Sie können es wie folgt tun:

SELECT * FROM ... WHERE name LIKE 'someone' 

(Es ist nicht die Lösung, aber in einigen Fällen ist sehr bequem)

"Die LIKE Oper tor macht ein Muster passenden Vergleich. Der Operand zu das Recht enthält das Muster, der linke Handoperand enthält die Zeichenfolge , um mit dem Muster übereinzustimmen. Ein Prozentzeichen ("%") im Muster entspricht einer beliebigen Folge von 0 oder mehr Zeichen in der Zeichenfolge. Ein Unterstrich ("_") in dem Muster stimmt mit jedem einzelnen Zeichen in der Zeichenfolge überein. Jedes andere Zeichen entspricht selbst oder es ist Groß-/Kleinschreibung Äquivalent (d.h. Fall unempfindlichen matching). (A bug: SQLite nur versteht Groß-/Kleinschreibung für ASCII Zeichen Der LIKE-Operator Fall empfindlich für Unicode-Zeichen, die über den ASCII-Bereich sind für beispielsweise der Ausdruck ‚a‘ wie ‚A‘ ist.. TRUE aber 'æ' LIKE 'Æ' ist FALSCH) „

+0

@ MM-BB ja, es sei denn, wir führen das LIKE für eine Spalte aus, die als COLLATE NOCASE deklariert (oder indiziert) wird, es wird einen vollständigen Scan der Zeilen durchführen. –

+0

Es ist kein Fehler, es ist eine dokumentierte Einschränkung. Die gleiche Seite, die in der Antwort zitiert wird, erwähnt die ICU-Erweiterung, die Unicode-Zeichen verwaltet. (Vielleicht war es im Jahr 2009 nicht der Fall) – stenci

140
SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE 
+3

Wenn Sie wie ich sind und weitere Dokumentation zum Sortieren möchten, können Sie es hier auf dieser Seite finden: http: //www.sqlite.org/datatype3.html Scrollen Sie einfach runter zu # 6.0 – Will

0

Wenn die Spalte vom Typ char dann müssen Sie den Wert anhängen Sie mit Leerzeichen abfragen, finden Sie in dieser Frage here.Dies neben der Verwendung vonoder eine der anderen Lösungen (obere(), usw.).

2

Eine weitere Option ist die Erstellung einer eigenen benutzerdefinierten Kollatierung. Sie können diese Sortierung dann für die Spalte festlegen oder sie zu Ihren Select-Klauseln hinzufügen. Es wird für Bestellungen und Vergleiche verwendet.

Dies kann verwendet werden, um 'VOILA' wie 'Voilà' zu machen.

http://www.sqlite.org/capi3ref.html#sqlite3_create_collation

die Sortierfunktion muss eine ganze Zahl zurück, die negativ, null oder positiv ist, wenn die erste Saite kleiner als, gleich oder größer als die zweiten, respectively.

1

Eine andere Option, die in Ihrem Fall sinnvoll sein kann oder nicht, besteht darin, eine eigene Spalte mit vorverringerten Werten Ihrer vorhandenen Spalte zu haben. Dies kann mit der SQLite-Funktion LOWER() ausgefüllt werden, und Sie können dann stattdessen eine Übereinstimmung für diese Spalte durchführen.

Offensichtlich fügt es Redundanz und ein Potenzial für Inkonsistenz hinzu, aber wenn Ihre Daten statisch sind, könnte es eine geeignete Option sein.

0

Sie können die gleiche Abfrage verwenden, um die entsprechende Zeichenfolge mit Tabellenwerten zu vergleichen.

Spaltenname aus Tabellenname auswählen, wobei Spaltenname wie 'jeweiliger Vergleichswert';

-1

Es funktioniert für mich perfekt. SELECT NAME FROM TABLE_NAME WHERE NAME = 'test Name' COLLATE NOCASE

Verwandte Themen