活动列表一个SQL解决排序问题

排序需求

活动列表排序规则要求如下:

  • 进行中/报名中,置顶的活动,置顶指数越高排越靠前
  • 进行中,距离现在越近越靠前
  • 报名中,距离现在越近越靠前
  • 已结束,置顶的活动
  • 已结束,距离现在越近越靠前的活动

实现SQL

# 数据表结构
CREATE TABLE `cps_activity` (
  `event_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '活动ID',
  `type` TINYINT(2) UNSIGNED NOT NULL COMMENT '活动类型',
  `uid` INT(10) UNSIGNED NOT NULL COMMENT '发起用户ID与user表关联',
  `title` VARCHAR(255) NOT NULL COMMENT '活动标题',
  `stime` INT(10) UNSIGNED DEFAULT '0' COMMENT '开始时间',
  `etime` INT(10) UNSIGNED DEFAULT '0' COMMENT '结束时间',
  `cftime` INT(10) UNSIGNED DEFAULT '0' COMMENT '报名截止时间',
  `is_top` tinyint(1) DEFAULT '0' COMMENT '置顶指数',
  `status` TINYINT(1) DEFAULT '1' COMMENT '状态 -1管理员删除 1正常 0异常',
  PRIMARY KEY (`event_id`),
  KEY `NewIndex1` (`uid`,`status`),
  KEY `searchs` (`stime`,`etime`,`status`)
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4

/* =================== */
# 列表查询SQL
SELECT event_id,TYPE,title,stime,etime,cftime,is_top,

IF(stime < UNIX_TIMESTAMP(NOW()) && UNIX_TIMESTAMP(NOW()) < etime ,1,0) aa, # 进行中的
IF(stime > UNIX_TIMESTAMP(NOW()),1,0) bb, # 未开始的
IF(etime > UNIX_TIMESTAMP(NOW()),1,0) cc, # 未结束的
ABS(CAST(stime AS SIGNED) - UNIX_TIMESTAMP(NOW())) AS dd ## 离开始时间越近数字越小

FROM cps_activity
WHERE STATUS = 1
ORDER BY cc DESC,is_top DESC,aa DESC,bb DESC,dd ASC

此处评论已关闭