You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL/Sequelize按状态分组排序:按进行中→待规划→逾期排序

解决方案

核心思路

不需要使用GROUP BY(因为我们不需要聚合数据,只是按状态分组排序),而是通过自定义排序优先级实现需求:

  1. 用CASE语句给三种状态分配排序权重:in progress(0) > planned(1) > overdue(2)
  2. 同一状态内按指定日期排序:
    • in progress:按endDate升序(结束早的优先)
    • planned:按startDate升序(开始早的优先)
    • overdue:按endDate升序(逾期早的优先)

MySQL 实现

假设今日日期已转为整数格式(如20221111代表2022-11-11),执行以下查询:

SET @today = 20221111; -- 替换为实际今日的整数日期

SELECT 
    *,
    CASE
        WHEN startDate <= @today AND @today <= endDate THEN 'in progress'
        WHEN @today < startDate THEN 'planned'
        ELSE 'overdue'
    END AS status
FROM items
ORDER BY
    -- 先按状态优先级排序
    CASE
        WHEN startDate <= @today AND @today <= endDate THEN 0
        WHEN @today < startDate THEN 1
        ELSE 2
    END ASC,
    -- 同一状态内按对应日期排序
    CASE
        WHEN startDate <= @today AND @today <= endDate THEN endDate
        WHEN @today < startDate THEN startDate
        ELSE endDate
    END ASC;

Sequelize.js 实现

先将今日日期转为整数格式,再通过sequelize.literal编写自定义排序逻辑(使用绑定参数避免SQL注入):

const { Op, sequelize } = require('sequelize');
const todayInt = 20221111; // 替换为实际今日的整数日期

const items = await Items.findAll({
    attributes: {
        include: [
            // 可选:返回每条数据的状态
            [sequelize.literal(`
                CASE
                    WHEN startDate <= :today AND :today <= endDate THEN 'in progress'
                    WHEN :today < startDate THEN 'planned'
                    ELSE 'overdue'
                END
            `), 'status']
        ]
    },
    order: [
        // 按状态优先级排序
        [sequelize.literal(`
            CASE
                WHEN startDate <= :today AND :today <= endDate THEN 0
                WHEN :today < startDate THEN 1
                ELSE 2
            END
        `), 'ASC'],
        // 同一状态内按对应日期排序
        [sequelize.literal(`
            CASE
                WHEN startDate <= :today AND :today <= endDate THEN endDate
                WHEN :today < startDate THEN startDate
                ELSE endDate
            END
        `), 'ASC']
    ],
    bind: { today: todayInt } // 绑定今日日期参数
});

说明

  • 若需要调整同一状态内的排序规则(比如in progress按startDate降序),只需修改第二个CASE语句的返回字段即可。
  • 示例中2023-01-01的排序结果可能存在笔误:按状态定义,item5应属于in progress(20221220 <= 20230101 <= 20231231),会和item6一起排在最前面。

内容的提问来源于stack exchange,提问作者robin14dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 11:25:58