Order By 字段,其中最长的字符串排在第一位

Order By field where longest string comes first

设置

我有三个 mysql 表,'course'、'section' 和 'time_slot'。我定期根据非规范化形式的 CSV 数据文件更新这些表。即

--------------------------------------------------
| subject | number | section | days | start_time |
--------------------------------------------------
| EDSC    | 209    | A       | M    | 8:00       |
--------------------------------------------------
| EDSC    | 209    | A       | TR   | 8:00       |
--------------------------------------------------
| EDSC    | 209    | A       | T    | 8:00       |
--------------------------------------------------
etc...

注意:这些似乎重叠的原因是因为它们可能发生在不同的日期,但这与这个问题无关

请注意它们是按星期几排序的,多天条目排在单日之前

我有这个 sql 查询试图匹配 CSV 的格式,然后以编程方式检查更新、添加、删除等。我的算法依赖于它们的正确顺序。

SELECT 
    c.subject, c.course_number, s.section_name, 
    t.days, t.start_time, t.end_time, t.building, t.room
FROM section s
JOIN course c on c.id=s.course_id
LEFT JOIN time_slot t on t.section_id=s.id
ORDER BY c.subject, c.course_number, s.section_name, t.start_time, t.days;

这会产生以下输出

--------------------------------------------------
| subject | number | section | days | start_time |
--------------------------------------------------
| EDSC    | 209    | A       | 1    | 8:00       |
--------------------------------------------------
| EDSC    | 209    | A       | 2    | 8:00       |
--------------------------------------------------
| EDSC    | 209    | A       | 2,4  | 8:00       |
--------------------------------------------------
etc...

注意,我使用数字作为天数,以便在不添加自定义排序规则的情况下进行订购,并将 CSV 天数转换为代码中的数字

问题:有没有办法按最长字符串在前的字段排序?我查看了 LENGTH(t.days) DESC,但我还需要 M 在 TR 之前出现。

订购部分问题的快速而有效的解决方案是将 'ZZZZZZ' 字符串附加到 order 子句中的字段:

...
ORDER BY t.days || 'ZZZZZZ' ASC
...

这样较短的字符串将被推到结果的底部,同时保留第一个字符的顺序。

只需要确保 'ZZZ' 字符串足够长并且 Z 实际上是您域中的最后一个字符。

说明 如果您有两个值 'A' 和 'AA' 并且您的目标是获得以下顺序:

  • AA
  • 一个

如果您只按字段排序,您将获得:

  • 一个
  • AA

这是因为缺少的字符比排序功能的任何其他字符都少。

所以您需要用最后一个字符替换缺失的字符来解决这个问题,添加 'ZZZZ' 就是这样做的,结果是:

  • AAZZZZ
  • AZZZZ