我需要对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
通过这种方式,我首先获得了按日期排序的所有即将到来的日期(从较低的值到较高的值),然后是从日期(从较高到较低)订购的所有过去日期
答案 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一起使用,并仍然使用分页器等。