【发布时间】:2015-12-14 16:56:55
【问题描述】:
我在 SQLite(在 Android 上)中对歌曲进行排序。我想订购它们:
- 不区分大小写
- 末尾有前导数字,按整数值。
- 没有标点符号(例如括号、句号、连字符、撇号)
我有 1 和 2 个工作(见下文)。但是,除了为每个字符调用 replace() 之外,我不知道如何替换每个字符(字母、数字和空格除外)。
除了对 replace() 的约 32 次调用之外,还有其他方法吗?
(ASCII 值 33-47,58-64,91-96,123-126)
这是一个测试表。理想情况下,值“n”应该按顺序排列。 (不,您不能通过n 订购;)
create table songs (n integer, name text);
insert into songs (n,name) values (6,'I''ll Be That Girl');
insert into songs (n,name) values (24,'1969');
insert into songs (n,name) values (9,'La Moldau');
insert into songs (n,name) values (20,'Pule');
insert into songs (n,name) values (7,'I''m a Rainbow Too');
insert into songs (n,name) values (21,'5 Years');
insert into songs (n,name) values (18,'Pressure');
insert into songs (n,name) values (13,'Lagan');
insert into songs (n,name) values (1,'any old wind that blows');
insert into songs (n,name) values (17,'Poles Apart');
insert into songs (n,name) values (8,'Imagine');
insert into songs (n,name) values (14,'Last Stop before Heaven');
insert into songs (n,name) values (3,'I Before E Except After C');
insert into songs (n,name) values (4,'i do, i do, i do');
insert into songs (n,name) values (22,'99 Luftballons');
insert into songs (n,name) values (12,'L''accord parfait');
insert into songs (n,name) values (15,'Pluto');
insert into songs (n,name) values (19,'The Promise');
insert into songs (n,name) values (2,'(Don''t Fear) The Reaper');
insert into songs (n,name) values (10,'L.A. Nights');
insert into songs (n,name) values (23,'911 is a Joke');
insert into songs (n,name) values (5,'Ichthyosaurs Are Awesome');
insert into songs (n,name) values (11,'Labradors are Lovely');
insert into songs (n,name) values (16,'P.O.D.-Boom');
这是上面 1 和 2 的解决方案:
SELECT n
FROM songs
ORDER BY
CASE WHEN name GLOB '[0-9]*' THEN 1
ELSE 0
END,
CASE WHEN name GLOB '[0-9]*' THEN CAST(name AS INT)
ELSE name
END
COLLATE NOCASE
对于这个测试集,它按以下顺序生成结果:2,1,3,4,6,7,5,8,12,10,9,11,13,14,16,15,17,18,20,19,21,22,23,24
我可以通过手动替换每个不需要的字符来修复这个特定的测试集:
SELECT n
FROM songs
ORDER BY
CASE WHEN name GLOB '[0-9]*' THEN 1
ELSE 0
END,
CASE WHEN name GLOB '[0-9]*' THEN CAST(name AS INT)
ELSE
replace(
replace(
replace(
replace(name,'.',''),
'(',''
),
'''',''
),
' ',' '
)
END
COLLATE NOCASE
【问题讨论】:
-
如果有帮助,我可以依赖 SQLite 3.8.6 或更高版本。目前我只针对 Android L,很快就会针对 Android M。
-
@Phrogz ..为什么不尝试将原始字符串长度和用
''(空字符串) 和order替换的标点符号的字符串长度之间的差异问题中的第 3 位? -
我不认为你明白我的意思。这就是我想要传达的。对于字符串 'ab,c' 它将是 len(orig_string) 为 4 并且 len(orig_string_with_punctuation 替换为 '') 为 3。所以这样你就可以得到
1的差异。对于没有标点符号的字符串,这个差异将为 0。因此您可以在order by子句中使用这些差异。希望你能得到我。 -
当您存储数据时,请创建一个干净的排序键。然后按提取数据排序。这将使您的生活变得更加简单。
-
@AllanS.Hansen 这是对媒体播放器从 mp3 id3 标签中实时提取的数据的 sqlite 查询。无法修改数据库。