【问题标题】:Conditional sorting in MySQLMySQL中的条件排序
【发布时间】:2014-06-30 11:27:50
【问题描述】:

我有一个包含以下相关字段的会议表:

  1. 会议名称(文字)
  2. 提交截止日期(日期)
  3. 通知日期(日期)
  4. 活动开始(日期)
  5. 活动结束(日期)

我想查询所有活动结束时间大于今天的会议,并排序如下:

  1. 首先,通知在未来的所有会议;在通知日期之前订购这些。
  2. 那么,通知过去的所有会议;按事件开始排序。

我试过了:

(SELECT * FROM conferences
 WHERE ev_end >= '2014-06-30'
 AND notification >= '2014-06-30'
 ORDER BY notification ASC)
UNION
(SELECT * FROM conferences
 WHERE ev_end >= '2014-06-30'
 AND notification < '2014-06-30'
 ORDER BY ev_start ASC);

但它不起作用,排序不正确。事实上,我根本看不出任何排序:当我省略两个 ORDER BY 子句时,结果的排序方式完全相同(即看起来是随机的)。

是否可以通过一个 SQL 查询来实现这一点?还是我必须进行两个单独的查询?

我知道这个问题:Conditional sorting in MySQL?,但我的情况完全不同。

【问题讨论】:

    标签: mysql sorting sql-order-by


    【解决方案1】:

    您可以通过将所有逻辑放在order by 子句中来使用单个查询来完成此操作:

    select *
    from conferences
    where ev_end >= '2014-06-30' 
    order by (notification >= '2014-06-30') desc,
             (case when notification >= '2014-06-30' then notification end) asc,
             (case when notification < '2014-06-30' then ev_start end) asc;
    

    请注意,union 明确不保证结果集的顺序。如果您希望结果集按特定顺序排列,那么您需要在查询的最外层使用 order by

    【讨论】:

    • 我认为您必须在 order by 子句之前删除 and
    • @Sadikhasan 。 . .谢谢。
    • 谢谢,这行得通(就像@Vatev 的解决方案一样)。我选择接受您的回答,因为您添加了一些解释。您能否解释一下order by (notification &gt;= '2014-06-30') 部分?这是做什么的?
    • (notification &gt;= '2014-06-30') 计算结果为 1 或 0,它对这些值进行排序。
    • @MalteSkoruppa 。 . .在 MySQL 中,布尔表达式被视为整数,“true”为1,“false”为0。所以该表达式是case when notification &gt;= '2014-06-30' then 1 else 0 end) desc 的简写,将匹配的行放在第一位,然后是其余的。
    【解决方案2】:
    SELECT *
    FROM conferences
    WHERE ...
    ORDER BY notification < '2014-06-30', 
             IF(notification < '2014-06-30', ev_start, notification)
    

    【讨论】:

      【解决方案3】:
      SELECT * 
      FROM conferences
      WHERE ev_end >= '2014-06-30'
      ORDER BY IF(notification >= '2014-06-30', notification, ev_start) ASC
      

      IF 用于返回通知或 ev_start 作为排序依据的值,具体取决于通知是否在未来

      【讨论】:

      • 这不起作用,因为它只返回通知过去的会议(AND notification &lt; '2014-06-30'),所以IF 子句将始终评估为FALSE,我错过了所有通知的会议日期在未来。
      • 实际上,这仍然不是我想要的,因为这不会将未来所有带有通知的会议置于过去所有带有通知的会议之上。在ORDER BYIF 子句之间应该有另一个(notification &gt;= '2014-06-30') DESC,
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-29
      • 1970-01-01
      相关资源
      最近更新 更多