按名称排序,不带“the”(和其他复杂代码)

Posted

技术标签:

【中文标题】按名称排序,不带“the”(和其他复杂代码)【英文标题】:ORDER BY name without leading "the" (and other complex code) 【发布时间】:2015-09-18 16:36:02 【问题描述】:

我正在从 SQLite 数据库中对歌曲名称进行排序,并且我想忽略任何前导的“The”进行排序。所以,例如:

1  Labradors are Lovely
2  The Last Starfighter
3  Last Stop before Heaven

This answer 在简单的情况下解决了这个需求:

SELECT name FROM songs
ORDER BY
  CASE WHEN instr(lower(name),'the ')=1 THEN substr(name,5)
       ELSE name
  END
COLLATE NOCASE;

但是,我已经在使用complex transformation on the name column。将两者结合起来,我得到了这个丑陋的非 DRY 代码:

SELECT n, name
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 CASE WHEN instr(lower(name),'the ')=1 THEN
                   replace(
                     replace(
                       replace(
                         replace(
                           substr(name,5),
                           '.',''
                         ),
                         '(',''
                       ),
                       '''',''
                     ),
                     '  ',' '
                   )
                 ELSE
                   replace(
                     replace(
                       replace(
                         replace(name,'.',''),
                         '(',''
                       ),
                       '''',''
                     ),
                     '  ',' '
                   )
                 END
  END
COLLATE NOCASE;

有没有办法在查询期间使用变量或其他东西,以便我可以干掉代码,并且只在一个位置而不是两个不同的 case 分支中进行所有标点符号替换?

【问题讨论】:

fyi [0-9]* 匹配所有字符串,包括空白字符串。我想你想要[0-9]+ @Bohemian 并不是说​​我会有任何空白的歌曲名称,但这在 SQLite 中不是这样,GLOB operator 不是正则表达式。 [0-9]* 是“从字符串的前面开始,找到一个数字,然后是零个或多个任意字符。”它是 /^\d.*$/ 的正则表达式 【参考方案1】:

这样的事情应该可以工作。

SELECT n, name FROM (
  SELECT n, name,
  CASE WHEN instr(lower(name),'the ')=1 THEN substr(name,5)
       ELSE name
  END AS NameWithoutThe
  FROM songs
) AS inr
ORDER BY
  CASE WHEN name GLOB '[0-9]*' THEN 1
       ELSE 0
  END,
  CASE WHEN name GLOB '[0-9]*' THEN CAST(NameWithoutThe AS INT)
       ELSE
         replace(
          replace(
            replace(
              replace(
                NameWithoutThe,
                '.',''
              ),
              '(',''
            ),
            '''',''
          ),
          '  ',' '
         )
  END
COLLATE NOCASE;

【讨论】:

谢谢!我喜欢使用选择创建转换值“变量”以供以后使用的解决方案。

以上是关于按名称排序,不带“the”(和其他复杂代码)的主要内容,如果未能解决你的问题,请参考以下文章

Unix 的 'ls' 按名称排序

MySQL按X排序然后分组按Y然后按字母顺序排列

如何在 GORM 中按排序顺序保存数据

核心数据 - NSFetchedResultController 按其他表字段排序数据

如何执行 SQL 游标转换

按多个条件对向量进行排序