繁体   English   中英

sqlite查询返回有序的区分大小写和不区分大小写的匹配

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM