【问题标题】:How to sort MySQL results with letters first, symbols last?如何对 MySQL 结果进行排序,首先是字母,最后是符号?
【发布时间】:2012-07-25 01:08:14
【问题描述】:

老读者,第一次发帖。

我正试图弄清楚如何为我正在编写的音乐应用程序对艺术家列表进行排序。

为了帮助理解数据库结构:我没有一个关系系统,其中歌曲表中的每首歌曲都有一个艺术家 ID,该 ID 引用艺术家表中的一行,我只是有一个歌曲列表,其中艺术家的名字是一个字符串在一列中。然后我在 MySQL 查询中使用 GROUP BY artist 来返回单个艺术家的列表。

我的应用程序以 JSON 编码数组的形式从我的服务器检索这些数据,该数组是以下 MySQL 查询的结果:

SELECT artist FROM songs GROUP BY artist ORDER BY artist ASC

但是,此查询会导致名称为 &i、+NURSE 和 2007excalibur2007 的艺术家排在字母结果之前(例如 AcousticBrony、ClaireAnneCarr、d.notive 等)。

我需要的是名称以数字和符号开头的艺术家按字母顺序排序的艺术家列表之后返回。

该解决方案可以基于 PHP,但我更喜欢在 MySQL 查询中完成它的优雅。

【问题讨论】:

  • "而不是有一个关系系统,其中歌曲表中的每首歌曲都有一个艺术家 ID 引用艺术家表中的一行,我只是有一个歌曲列表,其中艺术家的名字作为字符串一个专栏。”为什么?
  • AFAIK 这是不可能的。从理论上讲,您可以创建自定义排序规则,但这并非易事:forge.mysql.com/wiki/How_to_Add_a_Collation
  • 第一个问题做得很好!
  • @MikeS.:我的回答有什么问题?我发布了与 Ollie 几乎完全相同的解决方案。
  • @JacobPritchett:REGEXP 返回 0 或 1。如果名称以字母开头,REGEXP '^[a-z]' 返回 1,否则返回 0。然后按降序排序,因此 1 排在第一位。 REGEXP '^[^A-Za-z]' 如果以字母开头,则返回 1,但因为它是升序,所以 1 排在最后。

标签: php mysql arrays sorting


【解决方案1】:

这会将所有名称以 a-z 中的字母开头的艺术家放在不以字母开头的艺术家之前:

SELECT DISTINCT artist
FROM songs
ORDER BY artist REGEXP '^[a-z]' DESC, artist

在线查看:sqlfiddle


但您可能更喜欢使用简化名称存储第二列,以便您可以将它们按更有意义的顺序排列:

artists

artist            | simplified_name
------------------------------------
&i                | i
+NURSE            | nurse
2007excalibur2007 | excalibur

simplified_name 的值无法在 MySQL 中轻松生成,因此您可能希望使用通用编程语言提取所有艺术家,将其转换为简化名称,然后将结果填充到数据库中。

完成后,您可以使用以下查询:

SELECT DISTINCT artist
FROM artists
ORDER BY simplified_name

【讨论】:

  • 实际上我只是重新阅读了您的帖子,而您希望符号 其他匹配项之后,这不是我的答案。
  • 哦,哎呀。我想知道为什么我没有想到这么简单的解决方法。
  • 您使用REGEXP '^[a-z]' DESC, artist 进行的编辑做到了!非常感谢! :)
  • 马克,您对代理键建议的看法是正确的。另外,我在您编辑您的答案以包含额外的 ORDER BY 子句之前写了我的答案。
  • @OllieJones:好的。我不确定谁是第一个。我编辑的时间戳与您的帖子几乎相同。
【解决方案2】:

您可以添加一个额外的ORDER BY 子句,将非字母字符开头的项目放在最后,如下所示:

    SELECT artist
      FROM songs
  ORDER BY artist REGEXP '^[^A-Za-z]' ASC, artist

这应该会将所有不以 A-Z 或 a-z 开头的艺术家移到您的排序末尾。

【讨论】:

  • 这是最好的答案,尽管我不想承认。+1(Ollie 技术不错)
  • 谢谢,这似乎也有效。我很好奇为什么这会返回与ORDER BY artist REGEXP '^[a-z]' DESC, artist 相同的结果。 ^[a-z]^[^A-Za-z]有什么区别,为什么需要将降序改为升序?
【解决方案3】:
ORDER BY ASCII(SUBSTR(artist, 1, 1)) NOT BETWEEN 65 AND 122, artist

这会将所有以字母字符开头的艺术家排序在非字母字符之前。

请注意,由于 ascii 的工作方式,[ \ ] & _ ` 将被视为按字母顺序排列。如果这很重要,您可以将其拆分为两个布尔表达式,分别处理大写和小写字母。

或许:

ORDER BY ASCII(UPPER(SUBSTR(artist, 1, 1))) NOT BETWEEN 65 AND 90, artist

请注意,这仅适用于 ascii 字符。属于其他字符集的字母不会被识别。

【讨论】:

    【解决方案4】:

    如果你想先按符号排序

    • ★★★符号★★★
    • 101 护发
    • Abc
    • 默认

    然后使用下面的查询

    ORDER BY artist REGEXP '^[^A-Za-z0-9]' DESC, artist ASC
    

    【讨论】:

      猜你喜欢
      • 2017-05-11
      • 2012-08-12
      • 1970-01-01
      • 2015-12-09
      • 2014-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      相关资源
      最近更新 更多