11

我需要对 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  DESC , CASE WHEN past_or_future  = 1 THEN startdate END ASC, CASE WHEN past = 0 THEN startdate END DESC

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

4

3 回答 3

16

CASE即使在ORDER BY子句中你仍然可以做声明,

SELECT *
FROM tableName
ORDER BY (CASE WHEN DATE(dateColumn) < DATE(GETDATE())
              THEN 1
              ELSE 0
         END) DESC, dateColumn ASC
于 2012-09-11T08:01:00.297 回答
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与所有联合一样,如果两个子组件互斥,请确保使用,这样就不需要不必要的排序和删除重复操作。

于 2012-09-11T08:04:42.983 回答
0

通常你不能在不使用 UNION 的情况下对一列进行双向排序。UNION 有一些缺点,尤其是在您使用 ORM 时。如果您想通过即将到来的 ASC 订购过去的 DESC,您可以使用以下技巧:

选择你的日期列,如果(你的日期列)

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

于 2014-04-16T10:31:35.067 回答