在varchar字段的开头按字母顺序排序带有“The”,“A”,“An”等的记录

时间:2011-03-31 19:16:01

标签: mysql sql postgresql

我正在为这类问题寻找MySQL和PostgreSQL解决方案。

假设我有一些title字段的记录。标题是书籍或电影名称,如“帽子里的猫”和“罗宾汉”。但是虽然标题必须以原始形式显示,但它们应该按照图书馆对它们进行排序的方式进行排序,即通过将任何文章(如“The”或“An”)移动到标题的末尾。

所以“帽子里的猫”就好像它是“帽子里的猫”一样。

设计架构或编写查询的最佳方法是什么,以便这些记录按标题排序,就像库对标题排序一样? (我也希望我知道这种按标题排序的技术术语。)另外,我应该注意哪些性能考虑因素以及应该创建哪些索引?

5 个答案:

答案 0 :(得分:4)

为什么不在表格中添加“title_prefix”字段并将所有这些“the”和“a”字符串移到那里?在您订购时,您将使用“标题”字段,当您展示标题时,您可以以任何方式进行连接。

答案 1 :(得分:3)

创建一个自定义函数(sortableTitle,也许?),它将修改以不需要的单词开头的字符串。使用order by sortableTitle(title)完成查询语句。这将产生额外的CPU成本,但你必须通过基准来知道多少。

您可以创建一个由触发器填充的额外列(sortTitle)。这将占用一些空间,但随后您的服务器将能够按索引对行进行排序。

除了上述内容,您不能(不修改数据库服务器代码)直接创建所需顺序的索引。据我所知,这适用于MySQL和PostgreSQL。

答案 2 :(得分:2)

iTunes通过第二个字段实现了这一点,其中标题以所需的排序格式存储,并对其进行排序而不是标题。听起来好像很便宜,但是当你考虑每次执行一个按标题排序的select语句对每个标题进行字符串操作的性能影响时,每次插入或更新标题时都要对字符串进行操作,它会有道理。

答案 3 :(得分:1)

Select * from TitleTable 
Order by 
Case when substring(title,0,4) = 'The ' then substring(title, 4, len(title)-4)
when substring(title,0,3) = 'An ' then substring(title, 3, len(title)-3)
when substring(title,0,2) = 'A ' then substring(title, 2, len(title)-2)
else title 
end

答案 4 :(得分:1)

我建议您将title字段拆分为两个字段:mainTitlepre

添加标题时,检查它是否以“A”,“The”或其他前缀开头,并将其分割(可能带有触发器)到两个字段中。你的桌子看起来像这样:

| pre |   mainTitle    |
|-----|----------------|
| The | Cat in the Hat |
| A   | Space Odyssey  |
|     | Eyes Wide Shut |

因此,您可以在mainTitle字段上添加索引并将其用于排序。

如果要显示完整标题,请以两种形式之一连接两个字段。


  • 如果选择这种方式,则必须相应地修改用户在表格中搜索标题的代码。在搜索mainTitle字段之前,必须以相同的方式拆分给定的标题。

  • 您必须非常非常小心执行拆分的代码(触发器或其他),以便正确捕获某些特殊情况。您不希望显示A = BA B C: learn the alphabet本书并将其排序为= B, AB C: learn the alphabet, A