[英]sqlite query to return ordered case-sensitive AND case-insensitive hits
假设我有一个带有单词表的数据库,如下所示:
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)索引来节省数据库空间,因为无论如何它可能很少使用。 通常,我只会走一次,抓住第一击。
最有效的方法是什么?
为了使区分大小写和不区分大小写的搜索高效,您需要两个索引:
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字符,您需要安装自定义排序规则)。
我想你想要这样的东西:
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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.