sqlite高级区分大小写的查询

时间:2017-01-30 09:49:50

标签: sqlite

我在SQLite中搜索一种特殊的查询 对笔记表进行排序。

查询的结果应该是这样的:

id  oid
1    1
2    1,1
5    1,1,a
6    1,1,a,1
3    1,1,A
4    1,1,A,1

但是随着下面的代码,我收到了这个:

CREATE TABLE note (
id INTEGER PRIMARY KEY AUTOINCREMENT,
created DATETIME DEFAULT CURRENT_TIMESTAMP,
oid VARCHAR unique,
tit VARCHAR,
dsc VARCHAR
);

select id, oid from note
order by oid collate NOCASE

结果:

id  oid
1    1
2    1,1
5    1,1,a
3    1,1,A
6    1,1,a,1
4    1,1,A,1

有什么建议吗?

由于 --jonah

2 个答案:

答案 0 :(得分:2)

以下内容转换排序键,以便正常的区分大小写排序产生请求的结果:

如果有togglecase()函数,该函数将大写小写和小写大写(例如Hello => hELLO),可以ORDER BY togglecase(oid)和结果将按要求的顺序进行。

您可以定义此类函数并将其作为UDF公开给SQLite。也可以使用内置的SQLite函数编写这个函数,但我不太清楚它们使用它们给出答案。以下是Python中此类函数的示例:

def togglecase(s):
   def toggle(l):
       if l.isupper(): 
           return l.lower()
       if l.islower():
           return l.upper()
       return l
   return ''.join(toggle(l) 
                  for l in s)

请注意,为了获得正确的Unicode支持,它需要迭代字形。没有超过代码点。

看到这就是我所描述的:

>>> togglecase("1,1,A")
'1,1,a'
>>> togglecase("1,1,a")
'1,1,A'

可以在Python中测试这是否正确排序:

>>> sorted(["1", "1,1", "1,1,a", "1,1,a,1", "1,1,A", "1,1,A,1"])
['1', '1,1', '1,1,A', '1,1,A,1', '1,1,a', '1,1,a,1']

查看大写字母如何跟小写字母:

>> sorted(["1", "1,1", "1,1,a", "1,1,a,1", "1,1,A", "1,1,A,1"], key=togglecase)
['1', '1,1', '1,1,a', '1,1,a,1', '1,1,A', '1,1,A,1']

现在,如果你在SQLite中使用它,如:

SELECT id, oid 
FROM note
ORDER BY togglecase(oid)

这应该导致:

1   "1"
2   "1,1"
3   "1,1,a"
4   "1,1,a,1"
5   "1,1,A"
6   "1,1,A,1"

除了togglecase函数之外,代码未经测试。

答案 1 :(得分:1)

您正在获得该结果,因为排序被指定为NOCASE。这意味着“ a ”和“ A ”等于。因此,首先是“ a / A ”的行,之后没有任何内容,然后是“ a / A ”的行和之后的数据。

如果您进行CASE SENSITIVE查询,您将得到不同的结果。但是“ A ”出现在“ a ”之前,区分大小写:

SELECT id, oid 
FROM note
ORDER by oid

结果:

1   "1"
2   "1,1"
5   "1,1,A"
6   "1,1,A,1"
3   "1,1,a"
4   "1,1,a,1"