【问题标题】:MySQL order by date until a specific date, after it reverse orderMySQL 按日期排序,直到特定日期,在它反向排序之后
【发布时间】:2019-01-21 00:56:40
【问题描述】:

好的,所以我有一张这样的桌子

+----+-------+------------+
| id | title |    date    |
+----+-------+------------+
|  1 | aaa   | 2018-08-13 |
|  2 | bbb   | 2018-08-02 |
|  3 | ccc   | 2018-07-06 |
|  4 | ddd   | 2018-07-16 |
|  5 | fff   | 2018-07-13 |
+----+-------+------------+

我想按日期列升序对其进行排序,但仅在特定日期之前对其进行排序,之后我想对其进行降序排序,如下所示

+----+-------+------------+
| id | title |    date    |
+----+-------+------------+
|  4 | ddd   | 2018-07-16 |
|  2 | bbb   | 2018-08-02 |
|  1 | aaa   | 2018-08-13 |
|  5 | fff   | 2018-07-13 |
|  3 | ccc   | 2018-07-06 |
+----+-------+------------+

我以为我可以使用UNION,但我不知道如何使用它,或者它不接受每个SELECT 中指定的ORDER BY 子句。

编辑:我可能没有很好地解释自己。在我的查询中,我需要按日期升序对特定日期(> = 某个日期,在这种情况下让我们使用 2018-07-15)之后的所有行和之前的所有行进行降序排序。

【问题讨论】:

  • 这里有各种各样的技巧......你可能真的只需要其中的一两个 sqlfiddle.com/#!9/58a8ac/20
  • @Strawberry 你能把它作为一个答案,因为这个是唯一一个似乎可以正常工作的。
  • 很有趣,我没想到这样的事情实现起来如此复杂。
  • 我对这个问题不满意......所以我用联合创建了一个类似的问题,但我看到了其中的一些逻辑,所以我会发布答案。
  • 不过很好的练习。 :)

标签: php mysql sql mysql-workbench navicat


【解决方案1】:

您应该使用单个 order by 并且没有子查询:

order by (case when date >= @date then 1 else 0 end),  -- put more recent first
         (case when date >= @date then date end) asc,  -- order the first group ascending
         date desc  -- order by second group descending

【讨论】:

    【解决方案2】:

    参考D-Shih奠定的基础......

    SELECT id
         , title
         , date
      FROM 
         ( SELECT *
                , CASE WHEN date <'2018-07-15' THEN @i:=0 ELSE @i:=@i+1 END i
             FROM t
                , (SELECT @i:=0) vars
            ORDER  
               BY date
         ) x
     ORDER
        BY i=0, i, date DESC;
    

    http://sqlfiddle.com/#!9/58a8ac/20

    您可能并不真正需要上面显示的所有技术,但我只是在进行过程中编造这些东西......

    【讨论】:

    • 你是最好的。
    • 使用两个order bys 和一个子查询是不必要的昂贵。
    【解决方案3】:

    用子查询试试这个联合:

    select * from 
    (select *,ord=0 from tablename where id=2
    union
    select *,ord=1 from tablename where id<>2)a
    order by ord asc, date desc
    

    【讨论】:

    • 它部分工作,它确实将这两个日期分开,但它不会对它们进行不同的排序。
    【解决方案4】:

    @D-Shih 几乎做对了...

    SELECT *
    FROM yourtable
    ORDER BY (CASE
      WHEN `date`>"2018-07-06" THEN 'date'
      ELSE DATE("2018-07-06")
    ) ASC,
    `date` DESC;
    

    您可以使用 UNION 来完成,但这很快就会变得一团糟。

    您也可以将 CASE 语句实现为 LEAST()

    【讨论】:

    • 它不会在 MySQL 中产生我想要的东西,@Strawberry 对我的问题的评论是有效的。
    【解决方案5】:

    确切地知道你想使用的日期,你可以这样做:

    SELECT * FROM (
        SELECT 
            concat(1,'-',@firstquery := @firstquery + 1) as rownum, table_name.* 
        FROM 
            table_name, 
            (SELECT @firstquery:=0) fq 
        WHERE 
            date_column <= '2018-08-05' 
        ORDER BY 
            date_column ASC) a
    UNION ALL 
    SELECT * FROM (
        SELECT 
            concat(2,'-',@secondquery := @secondquery + 1) as rownum, table_name.* 
        FROM 
            table_name, 
            (SELECT @secondquery:=0) sq 
        WHERE 
            date_column > '2018-08-05' 
        ORDER BY 
            date_column DESC) b
    ORDER BY rownum ASC
    

    这是相当大的,但在这种情况下,我正在模拟基于每个子查询的行号并将其连接起来以便稍后排序。这意味着您也可以在某个时候向后订购。

    我喜欢这个的地方在于,我们在 rownum 中指定了基于联合之前订购的每个项目的顺序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-06
      相关资源
      最近更新 更多