【问题标题】:Order By field where longest string comes firstOrder By 最长字符串排在前面的字段
【发布时间】:2015-07-25 23:36:14
【问题描述】:

设置

我有三个 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 之前。

【问题讨论】:

  • 如果您的应用可以正常工作,那么也许您不必担心更改它。如果您将所有更改包装在一个事务中,您甚至不会看到删除和后续插入。
  • 可以在 order 子句中放几个字段:ORDER BY t.days ASC, LENGTH(t.days) DESC
  • @Bulat 我刚试过,但似乎只有第一个 ORDER BY 子句生效。第二部分仅影响在第一部分中被视为相等的记录。在这种情况下,“1”被认为小于“1,2”,因此不会应用长度排序。
  • 如果您删除问题部分并只留下与标题相关的第一个问题,您的问题会更好。问题 2,3 不相关/不完整,应作为单独的问题提出。

标签: java mysql csv collation


【解决方案1】:

订购部分问题的快速而持久的解决方案是将“ZZZZZZ”字符串附加到订单子句中的字段:

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

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

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

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

  • AA
  • 一个

如果你只是按你得到的字段排序:

  • 一个
  • AA

这是因为缺席 char 小于任何其他用于排序功能的 char。

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

  • AAZZZZ
  • AZZZZ

【讨论】:

  • 这个可以,但我不明白它是如何工作的。你能详细说明一下吗?
  • 哇,这非常漂亮,并且不会在我的实际数据中引入任何奇怪的东西,只是查询中的一个额外子句。谢谢。
猜你喜欢
  • 2022-12-09
  • 1970-01-01
  • 2011-05-25
  • 1970-01-01
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-26
相关资源
最近更新 更多