3

我正在开发一个 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 书)。使用本教程,我能够设置部分和索引,但在处理“The 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”,但我不知道如何将它整合到我的查询中,就像现在这样。

我希望这足够详细。请随时要求我澄清任何事情。与往常一样,提前致谢。

4

2 回答 2

1

最好的选择可能是在插入时检查这些条件,并将“The”放在标题的末尾(例如,“A Title 3, The”)。您可以编写一个简单的程序来更新当前数据库并将“The”标记到末尾。

但是,如果您真的想保持这种方式,请查看 case 表达式。这是一个相关主题: SQLite 是否支持 select 中的任何类型的 IF(condition) 语句

基本上,检查“The”或特殊字符的大小写,并在您的 SUBSTR 中使用该大小写。

于 2012-07-15T19:05:09.420 回答
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。在大多数数据库中,它会为非数字部分生成错误。

于 2012-07-15T19:44:46.917 回答