MySQL今日,过去,未来的订单

时间:2013-09-12 20:23:53

标签: php mysql sql sql-order-by

我正在尝试使用带有日期的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合并它们?

3 个答案:

答案 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