【问题标题】:Sorting data according to current date根据当前日期对数据进行排序
【发布时间】:2015-08-25 10:07:33
【问题描述】:

我有一张这样的posts 表格

+--------------------+--------------+
| Field              | Type         |
+--------------------+--------------+
| id                 | int(11)      |
| title              | varchar(255) |
| body               | text         | 
| published_at       | datetime     |
+--------------------+--------------+

我想要实现的是order published_at。通常我会这样做:

SELECT * FROM posts ORDER BY published_at;

但我在这里的要求是查询应该从当前日期获取结果,然后是之前的结果,然后从未来获取结果。

目前我的结果如下:

+-------------------------------+----+---------------------+
| title                         | id | published_at        |
+----------------------------------------------------------|
| Hello world                   |  1 | 2015-01-06 12:21:16 |
| 20+ Tools For RoR Development |  2 | 2015-08-25 12:21:23 |
| Angular JS tutorial           |  3 | 2015-09-31 10:51:55 |
| Visual search                 |  4 | 2015-03-12 12:27:26 |
| Ruby on Rails best practices  |  5 | 2015-01-21 00:00:00 |
+-------------------------------+----+---------------------+  

而我想要的结果是:

+-------------------------------+----+---------------------+
| title                         | id | published_at        |
+----------------------------------------------------------|
| 20+ Tools For RoR Development |  2 | 2015-08-25 12:21:23 |
| Hello world                   |  1 | 2015-01-06 12:21:16 |
| Ruby on Rails best practices  |  5 | 2015-01-21 00:00:00 |
| Visual search                 |  4 | 2015-03-12 12:27:26 |
| Angular JS tutorial           |  3 | 2015-09-31 10:51:55 |
+-------------------------------+----+---------------------+

【问题讨论】:

  • 在 MongoDB 中可以吗?
  • 我在 mongo 中使用聚合函数来管理这个。

标签: mysql sql


【解决方案1】:

不使用 UNION/CASE 的解决方案

SELECT * FROM posts
ORDER BY
    DATE(published_at)=DATE(NOW()) DESC,
    DATE(published_at)<DATE(NOW()) DESC,
    DATE(published_at)>DATE(NOW()) ASC`

检查这是否有效。它适用于受刺激的数据。您可以根据过去和未来日期的排序要求将 desc 更改为 asc

【讨论】:

  • 不错的一个。您可能希望通过published_at 再添加一个订单,以便按照您想要的方式对每个“组”中的数据进行排序。
  • 我们如何使用 Spring Data 为 MongoDB 实现这一点?
  • 我在 mongo 中使用聚合函数来管理它。感谢您从数据库中获取记录的逻辑。
【解决方案2】:

没有UNION(ALL)有一个可能的解决方案:

select
 id, title, published_at,
 case
   when date(published_at) = curdate() then '1-now'
   when date(published_at) < curdate() then '2-past'
   else '3-future'
   end as order_group
from t
order by order_group asc, published_at asc;

http://sqlfiddle.com/#!9/59c48/2

它需要一个文件排序才能运行,因此对于更大的数据可能不如 UNION ALL 快。 UNION 必须删除重复项,所以我希望它是相似的。

【讨论】:

  • 最好遵循不重复代码的规则。 “联合”答案包含多个选择,并且此答案在一个位置包含业务规则。
【解决方案3】:

试试这个:

SELECT * FROM posts WHERE published_at = CONVERT(DATE, GETDATE())
UNION
SELECT * FROM posts WHERE published_at != CONVERT(DATE, GETDATE()) ORDER BY published_at;

【讨论】:

  • 或者你可以添加 union all,这并不重要,因为两个查询返回不同的值
  • 这很重要,因为: 1. 联合消除重复。 2. 由于第一点,联合速度较慢,因为即使没有重复,它也会尝试消除重复。它做了更多的工作。
【解决方案4】:

使用不同的方法而不需要联合。

SELECT *
FROM(
    SELECT 1 AS Rank, title, id, published_at FROM posts WHERE DATE(published_at) = CURDATE()
    UNION ALL
    SELECT 2 AS Rank, title, id, published_at FROM posts WHERE DATE(published_at) < CURDATE()  
    UNION ALL
    SELECT 3 AS Rank, title, id, published_at FROM posts WHERE DATE(published_at) > CURDATE()
) a
ORDER BY rank, published_at 

输出:

Rank    title                           id  published_at
1       20+ Tools For RoR Development   2   August, 25 2015 12:21:23
2       Hello world                     1   January, 06 2015 12:21:16
2       Ruby on Rails best practices    5   January, 21 2015 00:00:00
2       Visual search                   4   March, 12 2015 12:27:26
3       Angular JS tutorial             3   October, 01 2015 10:51:55

SQL 小提琴:http://sqlfiddle.com/#!9/f6c1b/9/0

【讨论】:

  • "但是我在这里的要求是查询应该从当前日期获取结果,然后然后之前的结果,之后获取那些来自未来。”
  • @Matt 抱歉,我之前的评论没用,因为按 published_at 排序会将之前的条目排序在未来的条目之前。
  • 我们可以为以后的读者清理 cmets,我会删除我的
  • @Matt 你应该按等级排序,然后按published_at。
  • @FlorinGhita 是的,明白了! :)
【解决方案5】:
SELECT * 
FROM posts 
WHERE date(published_at) = CURDATE()

UNION ALL

SELECT * 
FROM posts 
WHERE date(published_at) != CURDATE() 
ORDER BY published_at;

CURDATE() 将给出今天的 date without time
date(published_at) 将从 published_at 修剪 time

【讨论】:

    【解决方案6】:

    没有联合,我们可以使用下面的查询得到结果

       SELECT * 
         CASE
           WHEN DATEDIFF(day, published_at, curdate()) > 0 then '0'
           WHEN DATEDIFF(day, published_at, curdate()) < 0 then 
            DATEDIFF(day, published_at, curdate())
           END AS dayInterval
        FROM posts
        order by dayInterval desc, published_at asc;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多