MySql查询结果的ORDER BY方向不同

时间:2013-06-08 06:35:40

标签: mysql sql-order-by

我正在尝试对我无法弄清楚的mysql查询进行一些排序。

id | status | created_at
------------------------
 1 | open   | 1348778070
 2 | closed | 1348711241
 3 | open   | 1348839204
 4 | closed | 1348738073
 5 | banned | 1348238422

如何按照ASC顺序订购上表,以便首先打开'开放'记录;然后非开放记录在DESC顺序中排名第二?换句话说,根据某些条件有一个动态的二级排序方向吗?

我尝试了两个SELECT查询的UNION,并在其中进行排序,这不起作用,因为UNION默认生成一组无序的行。

此外,我已经尝试了一个伪列,从大数字中减去created_at时间戳,用于已关闭的状态记录,因此我可以按ORDER BY ASC获得结果,如下所示......

SELECT table.*, (table.created_at) as tmp_order FROM table
  WHERE table.status = 'open'
UNION
  SELECT table.*, (999999999 - table.created_at) as tmp_order FROM table
WHERE table.status = 'closed'
ORDER BY tmp_order ASC

这有效,但我觉得必须有更好的方法。理想情况下,解决方案不包括上面的随机大数

4 个答案:

答案 0 :(得分:4)

<强>已更新

SELECT *
  FROM tmp_order
 ORDER BY FIELD(status, 'open') DESC, 
          CASE 
            WHEN status = 'open' 
              THEN created_at 
              ELSE (999999999 - created_at) 
          END 

SELECT *
  FROM tmp_order
 ORDER BY FIELD(status, 'open') DESC, 
          CASE 
            WHEN status = 'open' 
              THEN created_at END,
          CASE 
            WHEN status <> 'open' 
              THEN created_at END DESC

输出:

| ID | STATUS | CREATED_AT |
----------------------------
|  1 |   open | 1348778070 |
|  3 |   open | 1348839204 |
|  4 | closed | 1348738073 |
|  2 | closed | 1348711241 |
|  5 | banned | 1348238422 |

这是 SQLFiddle 演示。

答案 1 :(得分:1)

尝试:

SELECT id, status, 
if (status = 'open', created_at, 999999999 - created_at) as tmp_order 
FROM table 
ORDER BY status, tmp_order  

答案 2 :(得分:1)

这就是我要解决的问题:

SELECT
  id, status, created_at
FROM
  yourtable
ORDER BY
  status DESC,
  CASE WHEN status='open'   THEN created_at END,
  CASE WHEN status='closed' THEN created_at END DESC

答案 3 :(得分:0)

在您的情况下,您可以在一个查询中执行此操作,但通用解决方案适用于任何两个不同且无关的查询。排序是使用两个联合子查询,每个子查询都有自己的排序;

SELECT * FROM (
   SELECT *
  FROM table
  WHERE table.status = 'open'
  ORDER BY created_at DESC) x
UNION ALL
SELECT * FROM (
  SELECT *
  FROM table
  WHERE table.status = 'closed'
  ORDER BY created_at) y