我尝试使用
SELECT *
FROM `activity`
WHERE 1
ORDER BY
CASE WHEN `activity_date` >= '2019-06-14' THEN `activity_date` END ASC,
CASE WHEN `activity_date` < '2019-06-14' THEN `activity_date` END DESC,
`activity_date` ASC
但是它给了我2019-06-14
之前的降序顺序,等于或晚于2019-06-14
之后的升序顺序。喜欢
+----+------------+
| ID | Date |
+----+------------+
| 5 | 2019-06-12 |
| 3 | 2019-06-11 |
| 2 | 2019-06-10 |
| 4 | 2019-06-15 |
| 1 | 2019-06-16 |
+----+------------+
目前,我将其分为2个查询,以确保它可以使用WHERE子句返回正确的顺序。
但是,当我需要在许多页面中列出结果时,因为它们具有自己的行数,所以不能使用LIMIT start_limit, items_per_page
。
如果我使用UNION
合并结果,则顺序将再次不正确。因此,如果我可以使用1个单个查询并且可以返回正确的顺序,那就太好了!
答案 0 :(得分:2)
这是编写ORDER BY
子句的一种更为简洁的方法:
SELECT ID, Date
FROM activity
ORDER BY
Date < '2019-06-14',
IF(Date >= '2019-06-14', 1, -1) * DATEDIFF(Date, '2019-06-14');
第一个排序级别将记录放在2019-06-14
上或之后,然后是较早的记录。然后,在这两个组的每一个中,我们对升序排序以用于以后的记录,而对降序排序用于在前的记录。
一种适用于任何数据库的更通用的解决方案(保存DATEDIFF
,这是特定于MySQL的):
ORDER BY
CASE WHEN Date < '2019-06-14' THEN 1 ELSE 0 END,
(CASE WHEN Date >= '2019-06-14' THEN 1 ELSE -1 END) *
DATEDIFF(Date, '2019-06-14');
答案 1 :(得分:1)
您可以使用以下查询:
SELECT *
FROM activity
ORDER BY activity_date >= '2019-06-14' DESC,
CASE WHEN activity_date >= '2019-06-14' THEN activity_date END ASC,
CASE WHEN activity_date < '2019-06-14' THEN activity_date END DESC
它使用标志(activity_date >= '2019-06-14'
)确保活动日期首先排在2019-06-14
之后,然后两个大小写表达式确保这些日期排在上升的日期,日期在2019-06-14
之前下降。
答案 2 :(得分:1)
实际上,您的技术实际上没有任何问题,纯粹是您的第一种情况,当日期小于14时不输出任何内容,因此它输出NULL,并且null的值低于某个值,因此它们都日期小于第14位时按开始顺序排序:
感谢尼克提供了允许该镜头的dbfiddle
要整理出绑定在空MySQL上的这些行,然后查看orderby中的第二个子句,最后得到所有第14个前日期在第14个后日期之前
最简单的解决方法是在以下情况下将高日期作为ELSE:
SELECT *
FROM `activity`
ORDER BY
CASE WHEN `activity_date` >= '2019-06-14' THEN `activity_date` ELSE '2999-01-01' END ASC,
CASE WHEN `activity_date` < '2019-06-14' THEN `activity_date` END DESC
这将使屏幕快照中的所有空值变为2099-01-01(按时间顺序在真实日期之后),因此第一种排序会将其放在结果的末尾而不是开始。您发布的所有第14个日期都排在最前面,所有约会的前日期都绑定为2999-01-01,然后MySQL将使用第二个子句来整理联系
简而言之,是因为空值首先出现,并且将所有前置日期都转换为空值的第一种情况,将它们放在结果的顶部
但是,这并不是特别能说明问题的原因,为什么查询中的日期可能是2999,在这种情况下,我总是更倾向于使用更明确的排序。如果您先使用彼此先进行排序的东西(例如整数)来进行粗略的排序,那么
SELECT *
FROM `activity`
ORDER BY
CASE WHEN `activity_date` >= '2019-06-14' THEN 0 ELSE 1 END,
CASE WHEN `activity_date` >= '2019-06-14' THEN `activity_date` END ASC,
CASE WHEN `activity_date` < '2019-06-14' THEN `activity_date` END DESC
那么,很明显,您打算使第14个帖子排在第一位,而下一位开发人员无需记住并意识到空值排在第一位
输出如下:
2019-06-14 --sorted by 0, then date
2019-06-15 --sorted by 0, then date
2019-06-16 --sorted by 0, then date
2019-06-13 --sorted by 1, then date
2019-06-12 --sorted by 1, then date
2019-06-11 --sorted by 1, then date
作为一种常规技术,您可以在案例中添加任意数量的whens(使用不同的整数)以进行更多排序:
SELECT *
FROM `activity`
ORDER BY
CASE
WHEN activityrating = 'gold' THEN -1
WHEN `activity_date` >= '2019-06-14' THEN 0
ELSE 1
END,
...
首先放置所有黄金活动,按日期排序,然后放置所有第14个活动,依此类推