【问题标题】:Custom ORDER BY to ignore 'the'自定义 ORDER BY 以忽略“the”
【发布时间】:2010-11-20 03:03:58
【问题描述】:

我正在尝试对标题列表进行排序,但目前有一大堆标题以“The”开头。我希望忽略“The”,并希望处理第二个单词。这在 SQL 中是否可行,还是我必须在前端进行自定义工作?

例如当前排序:

  • 飞机
  • 人类之子
  • 全金属外壳
  • 低俗小说
  • 喷泉
  • 大逃亡
  • 女王
  • 扎多兹

排序会更好:

  • 飞机
  • 人类之子
  • 喷泉
  • 全金属外壳
  • 大逃亡
  • 低俗小说
  • 女王
  • 扎多兹

几乎就像记录存储为“喷泉,The”等一样。但如果可以的话,我不想那样存储它们,这当然是问题的症结所在。

【问题讨论】:

  • 感谢您提醒我有关 Zardoz 的信息。现在我会做关于浮头的噩梦。
  • 我很高兴有人发现了这一点:D
  • 现在,全金属外壳,有一部很棒的电影。或者就像我喜欢对我的约会对象说的那样:“我......在一个...... $#!+ 的世界里”。

标签: sql mysql sorting


【解决方案1】:

最好有一个计算列来执行此操作,以便您可以索引计算列并按此排序。否则,排序工作量很大。

那么您可以将计算列设置为:

CASE WHEN title LIKE 'The %' THEN stuff(title,1,4,'') + ', The' ELSE title END

编辑:如果 STUFF 在 MySQL 中不可用,则使用 RIGHT 或 SUBSTRING 删除前 4 个字符。但如果可能,仍然尝试使用计算列,以便索引更好。同样的逻辑应该适用于撕掉“A”和“An”。

罗伯

【讨论】:

  • 您可能还希望在排序列中将其全部设为小写,以获得不区分大小写的排序(和搜索)
  • 是的,如果您有区分大小写的情况。但我想,作为电影标题,大小写可能在输入中得到控制,因此您不需要根据小写等效项查找记录时对性能造成影响。
【解决方案2】:

类似:

ORDER BY IF(LEFT(title,2) = "A ",
            SUBSTRING(title FROM 3),
            IF(LEFT(title,3) = "An ",
              SUBSTRING(title FROM 4),
              IF(LEFT(title,4) = "The ",
                 SUBSTRING(title FROM 5),
                 title)))

但考虑到多次执行此操作的开销,您最好将标题排序值存储在另一列中......

【讨论】:

    【解决方案3】:

    我认为你可以做类似的事情

    ORDER BY REPLACE(TITLE, 'The ', '')
    

    虽然这会将任何出现的“The”替换为“”,而不仅仅是第一个“The”,尽管我认为这不会有太大影响。

    【讨论】:

    • 好吧,我也不喜欢我的想法,但至少解释一下它是否不是最好的解决方案,或者它是否甚至无法运行。
    【解决方案4】:

    处理此问题的最佳方法是创建一个包含您要专门用于排序输出的值的列。然后你只需要使用:

      SELECT t.title
        FROM MOVIES t
    ORDER BY t.order_title
    

    关于应该使用什么和不应该使用什么来排序标题会有各种规则。

    根据您的示例,另一种方法是使用以下内容:

       SELECT t.title
        FROM MOVIES t
    ORDER BY SUBSTR(t.title, INSTR(t.title, 'The '))
    

    您可以使用 CASE 语句来包含各种规则。

    【讨论】:

      【解决方案5】:

      您当然可以动态安排剥离“The”,尽管您很快就会发现您必须处理“A”和“An”(除了“A 代表 Alibi”等标题的特殊情况)。当“外国”电影进入组合时,你需要处理“El”和“La”(除了那个讨厌的边缘案例,“LA Story”)。然后混入一些德国电影,你需要处理“Der”和“Die”(除了那些讨厌的“Die Hard”边缘案例)。看到图案了吗?你正走在一条越来越长、越来越多特殊情况的道路上。

      避免越来越多的特殊情况的前进方法是按您希望的方式存储标题按您希望的方式存储标题。

      【讨论】:

      • 非常好的一点,虽然幸运的是在我的用例中完美是不必要的,所以这些边缘情况可以忽略,至少现在是这样。 +1 提到了这个问题。
      【解决方案6】:

      对于 SQLite

      ORDER BY CASE WHEN LOWER(SUBSTR(title,1,4)) = 'the ' THEN SUBSTR(title,5) ELSE title END ASC
      

      【讨论】:

        【解决方案7】:

        只删除第一个The的方法:

        =SUBSTITUTE(A1,"The ","",1) OR more reliably: 
        
        =IF(IF(LEFT(A1,4)="The ",TRUE)=TRUE,RIGHT(A1,(LEN(A1)-4)),A1)
        

        第二个基本上是说如果第一个左边的数字等于The,然后检查单元格中有多少个数字,并且只显示除The之外的右边数字。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-01
          • 2011-05-04
          • 2019-04-23
          • 2011-08-06
          • 1970-01-01
          相关资源
          最近更新 更多