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
设置
我有三个 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