我正在开发一个iOS应用程序,该应用程序使用FMDB来存储一系列书籍,这些书籍必须按字母数字排序(第一个字母,第二个数字)。但是,我还必须忽略非字母数字的前导字符,如星号或括号。我也必须忽略“The”。此外,这个已排序的数据将显示在索引的UITableView上,因此我需要能够获得每个部分中的主要字符列表和书名数量。
实施例 -
这是书名列表:
"A Title 1", "A Title 2", "The A Title 3", "B Title 1", "B Title 2", "B Title 3",
"*B Title 4", "C Title 1", "(The) C Title 2", "3 Title 1"
从这个列表中我会计算4个部分来标题('A','B','C','3')。我还会计算每个部分的书籍数量('A'-3书,'B'-4书,'C'-2书,'3'-1书)。使用this tutorial我能够设置部分和索引但是在处理诸如“A Title 3”,“* B Title 4”和“(The C Title 2”)之类的标题时遇到了麻烦。
目前,这是我正在使用的声明:
SELECT DISTINCT UPPER(SUBSTR(BookTitle, 1, 1)) AS Section,
COUNT(BookTitle) AS SectionCount
FROM BookTable
GROUP BY Section ORDER BY IFNULL(Section + 1, 0), Section
这将返回按字母数字排序的部分列表以及进入每个部分的书籍数量。问题在于,我的“T”部分中有太多书籍,因为它以“The”作为主要角色获得所有书籍。更不用说我正在获取特殊字符的部分,例如<或*当我想忽略这些。我想我需要修剪任何非字母数字字符和任何“The”,但我不知道如何将它整合到我的查询中。现在就这样。
我希望这足够详细。请随时让我清理一切。一如既往,提前谢谢。
答案 0 :(得分:1)
最佳选择可能是在插入时检查这些条件,并在标题末尾加上“The”(例如,“A Title 3,The”)。您可以编写一个简单的程序来更新当前数据库,并将“The”放到最后。
但是如果你真的想保持这种方式,请查看案例表达式。这是一个相关的主题: Does sqlite support any kind of IF(condition) statement in a select
基本上,请检查“The”或特殊字符的大小写,并在SUBSTR中使用该大小写。
答案 1 :(得分:1)
与其他语言相比,SQL中的字符串操作通常是“回归基础”。您可以采取以下一种方法:
select upper(substring(titleclean, 1, 1)) as Section, count(*)
from (select bt.*,
(case when upper(substring(titletrim, 1, 4)) = 'THE ' or
upper(sutring(titletim, 1, 5)) = 'THE) '
then substring(titletrim, 5, 1000)
else titletrim
end) as titleclean
from (select bt.*, ltrim(title, '()*') as titletrim
from booktable bt
) bt
) bt
group by upper(substring(titleclean, 1, 1))
order by (case when substring(titleclean, 1, 1) between '0' and '9' then 1
else 0
end),
Section
这是通过在子查询中分配变量来进行字符串操作。我认为这些遵循你想要的规则。最里面的ltrim()正在删除你不想要的初始变量。
我将表达式“ifnull(section + 1,0)”更改为更清晰的范围比较。您的版本可能适用于SQLite。在大多数数据库中,它会为非数字部分生成错误。