【问题标题】:Sorting Events in MySQL by start and / or end date按开始和/或结束日期对 MySQL 中的事件进行排序
【发布时间】:2020-03-25 08:46:18
【问题描述】:

我有以下起始位置:

表格中包含有开始和结束日期的事件。

我想按以下维度对查询中的这些事件进行排序:

当前事件 > 未来事件 > 已完成事件

SELECT 
    startAt,
    endAt,
    (
        CASE
            WHEN DATE(endAt) > DATE(NOW()) AND DATE(startAt) < DATE(NOW()) THEN 1
            WHEN DATE(endAt) > DATE(NOW()) AND DATE(startAt) > DATE(NOW()) THEN 0
            ELSE -1
        END
    ) as position
FROM 
    events
ORDER BY
    position DESC

现在的问题:

按三个类别排序适用于上述查询,但在类别内必须应用以下排序:

当前事件(按结束日期排序)> 未来事件(按开始日期排序)> 已完成事件(按结束日期排序)

因此,首先所有即将到期的正在运行的事件将按降序排列(即比之前的事件有更多时间),然后所有即将开始的未来事件按降序排列(即比之前的事件开始晚),然后所有已完成的事件按降序排列。

在@Tim Biegeleisen 的帮助下解决

SELECT 
    startAt,
    endAt
FROM 
    events
ORDER BY
    (
        CASE
            WHEN endAt > CURDATE() AND startAt < CURDATE() THEN 1
            WHEN endAt > CURDATE() AND startAt > CURDATE() THEN 0
            ELSE -1
        END
    ) DESC,
    (
        CASE 
            WHEN startAt < CURDATE() THEN endAt 
            ELSE startAt 
        END
    ) ASC

【问题讨论】:

    标签: mysql sql sorting date sql-order-by


    【解决方案1】:

    你可以试试这个逻辑:

    SELECT
        startAt,
        endAt
    FROM events
    ORDER BY
        CASE WHEN startAt < CURDATE() THEN endAt ELSE startAt END;
    

    上述ORDER BY子句的逻辑是,如果一个事件的开始日期严格小于现在,那么这意味着该事件要么正在进行中,要么完全结束,在这种情况下,我们使用它的endAt进行排序价值。否则,我们使用startAt 进行排序。

    根据您下面的 cmets,您似乎还想先按事件状态对记录进行排序,然后在每个组内排序:

    SELECT startAt, endAt
    FROM events
    ORDER BY
        CASE WHEN endAt > CURDATE() AND startAt < CURDATE() THEN 0
             WHEN endAt > CURDATE() AND startAt > CURDATE() THEN 1
             ELSE 2 END,
        CASE WHEN startAt < CURDATE() THEN endAt ELSE startAt END;
    

    【讨论】:

    • 我认为你和我的组合是必需的还是?
    • 您还想将三个不同的类别分别分组吗?您的问题并不清楚这一点。
    • 对不起 :) 但我用你的回答解决了这个问题,并在我的问题中添加了完整的答案。
    【解决方案2】:
    Try case statement to select he date for order.
    
      SELECT 
        startAt,
        endAt,
        (
            CASE
                WHEN DATE(endAt) > DATE(NOW()) AND DATE(startAt) < DATE(NOW()) THEN 1
                WHEN DATE(endAt) > DATE(NOW()) AND DATE(startAt) > DATE(NOW()) THEN 0
                ELSE -1
            END
        ) as position
      FROM 
            events
      ORDER BY
          CASE
              WHEN DATE(endAt) > DATE(NOW()) AND DATE(startAt) < DATE(NOW()) THEN endAt
              WHEN DATE(endAt) > DATE(NOW()) AND DATE(startAt) > DATE(NOW()) THEN startAt
          ELSE endAt
          END DESC
    

    【讨论】:

    • 我认为@Tim Biegeleisen 的答案是您的一个较短的版本,但无论如何感谢您的回答。
    猜你喜欢
    • 1970-01-01
    • 2018-04-30
    • 2023-03-17
    • 2014-03-11
    • 2018-12-17
    • 1970-01-01
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    相关资源
    最近更新 更多