如何按事件首次出现日期分组排序事件标题及时间?
解决方案
你可以通过窗口函数计算每个event_title组的最早日期,以此作为分组排序的依据,同时保留组内按日期升序的逻辑。修改后的SQL如下:
SELECT el.event_title, se.event_eventDateAndTime FROM events__events_list el JOIN events__sub_events se ON el.UID = se.event_masterEvent WHERE se.event_eventDateAndTime BETWEEN CURDATE() AND (CURDATE() + INTERVAL 45 DAY) ORDER BY -- 先按每组的最早日期排序,确定组的整体顺序 MIN(se.event_eventDateAndTime) OVER (PARTITION BY el.event_title) ASC, -- 确保同标题事件聚在一起(避免同最早日期的不同组混乱) el.event_title ASC, -- 组内按日期升序排列 se.event_eventDateAndTime ASC;
逻辑说明
MIN(se.event_eventDateAndTime) OVER (PARTITION BY el.event_title):这个窗口函数会为每个event_title组计算出该组内最早的事件日期,用这个值作为组的排序键,就能让最早有活动的组排在前面。- 第二个排序条件
el.event_title是兜底逻辑,防止不同组但最早日期完全相同时,同标题事件被拆分。 - 最后
se.event_eventDateAndTime ASC保证组内的事件严格按时间先后排列。
如果你的SQL版本不支持窗口函数(比如MySQL 5.x及更早版本),可以用子查询预计算每组的最早日期,再关联排序:
SELECT el.event_title, se.event_eventDateAndTime FROM events__events_list el JOIN events__sub_events se ON el.UID = se.event_masterEvent -- 子查询获取每个主事件对应的最早子事件日期 JOIN ( SELECT el2.UID, MIN(se2.event_eventDateAndTime) AS earliest_date FROM events__events_list el2 JOIN events__sub_events se2 ON el2.UID = se2.event_masterEvent WHERE se2.event_eventDateAndTime BETWEEN CURDATE() AND (CURDATE() + INTERVAL 45 DAY) GROUP BY el2.UID ) AS group_dates ON el.UID = group_dates.UID WHERE se.event_eventDateAndTime BETWEEN CURDATE() AND (CURDATE() + INTERVAL 45 DAY) ORDER BY group_dates.earliest_date ASC, el.event_title ASC, se.event_eventDateAndTime ASC;
补充说明
子查询版本通过提前计算每个主事件的最早子活动日期,再将这个日期作为排序依据,同样能实现需求,适配不支持窗口函数的老版本数据库。
内容的提问来源于stack exchange,提问作者Blind Trevor
相关产品推荐
相关产品推荐

