我正在尝试使用带有日期的ORDER BY
按以下顺序从我的表中获取记录:
TODAY (9 PM)
TODAY (7 PM)
TODAY (9 AM)
TODAY (7 AM)
PAST (3 DAYS AGO)
PAST (2 DAYS AGO)
PAST (1 DAYS AGO)
FUTURE (IN 1 DAY)
FUTURE (IN 2 DAYS)
FUTURE (IN 3 DAYS)
目前我正在使用:
SELECT *
FROM my_table
ORDER BY
IF(DATE(my_date) = DATE(NOW()), 0, 1) ASC,
IF(DATE(my_date) < DATE(NOW()), 0, 1) ASC,
my_date ASC
但这给了我:
TODAY (7 AM) - WRONG
TODAY (9 AM) - WRONG
TODAY (7 PM) - WRONG
TODAY (9 PM) - WRONG
PAST (3 DAYS AGO)
PAST (2 DAYS AGO)
PAST (1 DAYS AGO)
FUTURE (IN 1 DAY)
FUTURE (IN 2 DAYS)
FUTURE (IN 3 DAYS)
我尝试使用DESC
更改“今天”排序:
IF(DATE(my_date) = DATE(NOW()), 0, 1) DESC,
但是它只是将记录发送到最底层(甚至低于未来的结果)。这可能只与SQL有关,还是我必须使用CodeIgniter的where()
运行多个查询并使用PHP合并它们?
答案 0 :(得分:5)
我认为这符合规定的要求:
SELECT t.*
FROM my_table t
ORDER
BY DATE(t.my_date)=DATE(NOW()) DESC
, IF(DATE(t.my_date)=DATE(NOW()),t.my_date,DATE(NULL)) DESC
, t.my_date ASC
让我们解开一点。
ORDER BY中的第一个表达式将评估为1
(如果条件测试为真),0
(如果它为假)或NULL
(如果其中一个)表达式为NULL。)我们想要降序,以获得条件为'true'的行首先排序。
第二个表达式是IF函数。如果my_date值的日期部分是今天的日期,那么我们返回my_date
。我们希望按降序排序(按照规范)。否则,我们想要返回一个常量,以便所有其余的行被认为是“相等的”。
第三,我们按my_date值按升序排序。这不会影响今天的行,这些行已经按降序排序,因此这实际上只会影响到此为止“相等”的行(这将是“今天不是”)。 my_date值为NULL的任何行应该最后结束(ORDER BY中的第一个表达式实际上保证了我们。)
答案 1 :(得分:4)
Parado的答案正确地分隔了这些值。但订购也因集团而异。值将在当天下降,然后在其他日期上升。这是一种方式:
SELECT *
FROM my_table
ORDER BY (case when DATE(my_date) = DATE(NOW())
then my_date
else date('2000-01-01')
end
) desc,
my_date asc;
可以合并第二组。当日期按升序排序时,过去就在未来之前。
编辑:
`date('2000-01-01')的目的是使NULL值(即今天不是)去最后。您可以使用三部分逻辑来完成此操作:
SELECT *
FROM my_table
ORDER BY (case when DATE(my_date) = DATE(NOW()) then 1 else 2 end),
(case when DATE(my_date) = DATE(NOW())
then my_date
end
) desc,
my_date asc;
答案 2 :(得分:3)
尝试在order by
子句和my_date
列之后使用CASE语法,如下所示
SELECT *
FROM my_table
ORDER BY
CASE
WHEN DATE(my_date) = DATE(NOW()) THEN 0
WHEN DATE(my_date) < DATE(NOW()) THEN 1
WHEN DATE(my_date) > DATE(NOW()) THEN 2
ELSE 3
END , DATE(my_date) desc