我目前正在制作一个包含演出议程的艺术家网站。我希望它在开头(asc)列出第一个即将到来的演出,并在即将到来的演出之后列出过去的演出。我目前的解决方案是两个不同的查询,一个调用即将发生的事件,一个调用过去的事件,但我认为找出一种合并它们的方法会更整洁。有谁知道这是否可能,以及如何?
我就是这样开始的;
SELECT *
FROM agenda
INNER JOIN organizer ON agenda.agenda_organizer=organizer.organizer_id
SELECT *
FROM agenda
INNER JOIN organizer ON agenda.agenda_organizer=organizer.organizer_id
ORDER BY
CASE WHEN yourDateColumn > NOW() THEN 1
WHEN yourDateColumn < NOW() THEN 2
END ASC,
yourDateColumn
使用技巧可以在两个方向上订购同一列:
SELECT yourDateColumn,IF(yourDateColumn)<NOW(),DATEDIFF(yourDateColumn),NOW()) * -1000000000,UNIX_TIMESTAMP(STR_TO_DATE(CONVERT_TZ(e.startDate,e.timeZone,'Europe/Paris'), '%Y-%m-%d'))) AS diff FROM yourTable ORDER BY DIFF ASC;
这里的关键是乘以足够大的负数,因此日期最终按即将到来的 ASC 排序,然后通过 DESC。
你可以试试这个:
SELECT *
FROM
(SELECT * FROM agenda WHERE yourDateColumn > NOW() ORDER BY yourDateColumn ASC) future
UNION ALL
SELECT *
FROM
(SELECT * FROM agenda WHERE yourDateColumn < NOW() ORDER BY yourDateColumn DESC) past
这应该选择第一个即将发生的事件 ASC,然后选择过去的事件 DESC
如果您使用UNION,那么您可以巧妙地执行这两个语句 - 因为每个ORDER BY都只是在日期字段上,您知道它将使用索引来保持您的查询快速:
SELECT *
FROM agenda
INNER JOIN organizer ON agenda.agenda_organizer=organizer.organizer_id
WHERE yourDateColumn > NOW()
ORDER BY yourDateColumn ASC
UNION ALL
SELECT *
FROM agenda
INNER JOIN organizer ON agenda.agenda_organizer=organizer.organizer_id
WHERE yourDateColumn < NOW()
ORDER BY yourDateColumn DESC