我想通过字符串匹配从 sqlite3 数据库中选择记录。但是如果我在 where 子句中使用 '=',我发现 sqlite3 是区分大小写的。谁能告诉我如何使用不区分大小写的字符串比较?
您可以在 SELECT
查询中使用 COLLATE NOCASE
:
SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE
此外,在 SQLite 中,您可以通过在列定义中指定 collate nocase
(其他选项是 binary
(默认值)和 rtrim
;请参阅 here )。您也可以在创建索引时指定 collate nocase
。例如:
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);
涉及 Test.Text_Value
的表达式现在应该不区分大小写。例如:
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
优化器还可以潜在地利用索引在列上进行不区分大小写的搜索和匹配。您可以使用 explain
SQL 命令检查这一点,例如:
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
SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE
你可以这样做:
SELECT * FROM ... WHERE name LIKE 'someone'
(这不是解决方案,但在某些情况下非常方便)
“LIKE 运算符进行模式匹配比较。右侧的操作数包含模式,左侧的操作数包含与模式匹配的字符串。模式中的百分号 (“%”) 匹配任何零或多个序列字符串中的字符。模式中的下划线(“_”)匹配字符串中的任何单个字符。任何其他字符匹配自身或其小写/大写等效项(即不区分大小写的匹配)。(一个错误:SQLite 只能理解ASCII 字符的大写/小写。LIKE 运算符对超出 ASCII 范围的 unicode 字符区分大小写。例如,表达式 'a' LIKE 'A' 为 TRUE,但 'æ' LIKE 'Æ' 为 FALSE。) 。”
%
,这将产生意想不到的结果
这不是特定于 sqlite 的,但你可以这样做
SELECT * FROM ... WHERE UPPER(name) = UPPER('someone')
Jóga
之类的东西会失败
另一种选择是创建您自己的自定义排序规则。然后,您可以在列上设置该排序规则或将其添加到您的选择子句中。它将用于排序和比较。
这可以用来制作 'VOILA' LIKE 'voilà'。
http://www.sqlite.org/capi3ref.html#sqlite3_create_collation
如果第一个字符串分别小于、等于或大于第二个字符串,则整理函数必须返回一个负数、零或正数。
在您的情况下可能有意义或可能没有意义的另一个选项是实际上有一个单独的列,其中包含现有列的预降分值。这可以使用 SQLite 函数 LOWER()
填充,然后您可以在此列上执行匹配。
显然,它增加了冗余和潜在的不一致,但如果您的数据是静态的,它可能是一个合适的选择。
它完美地为我工作。 SELECT NAME FROM TABLE_NAME WHERE NAME = 'test Name' COLLATE NOCASE
简单地说,您可以在 SELECT 查询中使用 COLLATE NOCASE:
SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE
像这样使用
"select * from $pwsXDataHistory where type = '$type' COLLATE NOCASE and $t_uStatus != '$DELETE' order by $t_name COLLATE NOCASE asc ");
您可以使用类似查询将相应的字符串与表值进行比较。
从 table_name 中选择列名,其中列名如“各自的比较值”;
不定期副业成功案例分享
COLLATE NOCASE
添加到索引中:“The default collating sequence is the collating sequence defined for that column in the CREATE TABLE statement.”COLLATE NOCASE
仅适用于 ASCII 文本。一旦您的列值中有“FIANCÉ”或“voilà”,它就不会与“fiancé”或“VOILA”匹配。启用 ICU 扩展程序LIKE
becomes case-insensitive 后,'FIANCÉ' LIKE 'fiancé'
为真,但'VOILA' LIKE 'voilà'
仍为假。 ICU+LIKE 的缺点是不使用索引,所以在大表上可能会很慢。select * from tbl where firstname='john' and lastname='doe' COLLATE NOCASE
在lastname
上将不区分大小写。要在firstname
上不区分大小写,请写成:select * from tbl where firstname='john' COLLATE NOCASE and lastname='doe'
。它特定于那一列,而不是整个where
子句。