4

我正在尝试对我无法弄清楚的 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 时间戳,用于关闭的状态记录,所以我可以按 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

4 回答 4

5

更新

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

输出:

| 身份证 | 状态 | 创建_AT |
----------------------------
| 1 | 开放| 1348778070 |
| 3 | 开放| 1348839204 |
| 4 | 关闭| 1348738073 |
| 2 | 关闭| 1348711241 |
| 5 | 禁止| 1348238422 |

这是SQLFiddle演示。

于 2013-06-08T07:07:03.937 回答
1

尝试:

SELECT id, status, 
if (status = 'open', created_at, 999999999 - created_at) as tmp_order 
FROM table 
ORDER BY status, tmp_order  
于 2013-06-08T07:04:14.260 回答
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
于 2013-06-08T07:25:36.617 回答
0

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

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
于 2013-06-08T06:53:17.253 回答