让我们说我有一个包含单词表的数据库,如下所示:
CREATE TABLE Words (
Id integer PRIMARY KEY NOT NULL,
Word text NOT NULL
);
CREATE INDEX Word_Index ON Words (Word ASC);
sqlite> SELECT * FROM Words;
Id|Word
1|apple
2|Apple
3|Jack
4|jack
为了简单起见,我只想说我只关心ascii字符,只要区分大小写。
我想要做的是执行Word搜索并首先返回返回确切区分大小写匹配的行,然后返回匹配的所有行,忽略大小写,不重复。 例如,SELECT * FROM Words WHERE ...' Apple ' 会回来:
2|Apple
1|apple
同样,SELECT * FROM Words WHERE ...' apple ' 会回来:
1|apple
2|Apple
我主要关注区分大小写的匹配,但希望它们之后是不区分大小写的匹配,作为后备。我期待通常我会得到区分大小写的匹配,这就是为什么我有一个区分大小写的索引。我意识到不区分大小写的回退将无法使用索引,但我选择不使用第二个(COLLATE NOCASE)索引以节省数据库中的空间,因为它可能不经常使用。通常我只会踩到一次,抓住第一击。
最有效的方法是什么?
答案 0 :(得分:2)
要使区分大小写和不区分大小写的搜索更有效,您需要两个索引:
CREATE INDEX Word_Index ON Words (Word);
CREATE INDEX Word_Index_nocase ON Words (Word COLLATE NOCASE);
当您使用ORDER BY进行操作时,无法使用有效的索引查找;您必须对区分大小写和不区分大小写的匹配执行单独的查找,并从第二个结果中筛选出重复项:
SELECT *
FROM Words
WHERE Word = 'Apple'
UNION ALL
SELECT *
FROM Words
WHERE Word COLLATE NOCASE = 'Apple'
AND Word <> 'Apple';
(要处理非ASCII字符,您需要安装自定义排序规则。)
答案 1 :(得分:0)
我想你想要这样的东西:
SELECT *
FROM Words
WHERE LOWER(col) = LOWER('Apple')
ORDER BY (CASE WHEN col = 'Apple' THEN 1 ELSE 2 END),
col;
默认情况下,SQLite区分大小写。
你可以尝试这个,但我不知道它是否会使用索引:
SELECT *
FROM Words
WHERE col = 'apple' COLLATE NO CASE
ORDER BY (CASE WHEN col = 'Apple' THEN 1 ELSE 2 END),
col;