在即将到来的日期之后按日期订购过去的日期

时间:2012-09-11 07:58:37

标签: mysql sql date sql-order-by

我需要对MySql数据库中的表执行查询,其中结果行的顺序如下:

如果今天是10/09/12:

...
11/09/12 
12/09/12
15/09/12
08/09/12  <--here start the past dates
07/09/12
05/09/12
....

有没有办法直接在MySQL中实现这个?


我已经解决了这个问题:

首先,select语句包含一个新的布尔值,用于标记日期是过去还是将来:

SELECT DISTINCT *,CASE  WHEN startdate < CURDATE() THEN 0
                ELSE 1 END AS past_or_future 

其次,我做了一个双'Order by':首先在past_or_future布尔值上然后在日期上,条件如下:

ORDER BY past_or_future  DESC , CASE WHEN past_or_future  = 1 THEN startdate END ASC, CASE WHEN past = 0 THEN startdate END DESC

通过这种方式,我首先获得了按日期排序的所有即将到来的日期(从较低的值到较高的值),然后是从日期(从较高到较低)订购的所有过去日期

3 个答案:

答案 0 :(得分:11)

即使在CASE子句

中,您仍然可以ORDER BY语句
SELECT *
FROM tableName
ORDER BY (CASE WHEN DATE(dateColumn) < DATE(GETDATE())
              THEN 1
              ELSE 0
         END) DESC, dateColumn ASC

答案 1 :(得分:4)

是的,一种方法是将两个查询与“更强大”的排序键结合在一起(我在下面使用的是位置而不是列名):

select 1 as uberkey, date1, column2
  from mytable
  where data1 >= '2012-10-09'
union all
select 2 as uberkey, date1, column2
  from mytable
  where data1 < '2012-10-09'
order by 1 asc, 2 asc

这将使用uberkey作为主要排序字段,以便以后的日期先到。您可以在显示数据时忽略此列。

由于case必须对每一行进行翻译,因此case等每行功能通常会更有效。带有where子句的两个查询可以简单地使用索引来丢弃行的其他“一半”,并对检索到的那些使用常量。

并且(虽然我对MySQL没有特别的了解,但我自己也是一个DB2人员)智能DBMS'实际上可以并行查询的两个子组件以提高效率。

与所有联盟一样,如果两个子组件是互斥的,请确保使用union all,这样就不需要进行不必要的排序和删除重复操作。

答案 2 :(得分:0)

通常,您无法在不使用UNION的情况下在两个方向上对一列进行排序。如果你使用ORM,UNION会有一些不足之处。如果您想通过即将到来的ASC订购过去的DESC,您可以使用技巧:

选择yourDateColumn,IF(yourDateColumn)

您也可以将它与ORM一起使用,并仍然使用分页器等。