MySQL复杂的ORDER BY问题

时间:2014-12-12 17:44:14

标签: mysql sql-order-by find-in-set

由于需求的变化,我重新访问了几个月前创建的界面。更多功能,更多数据。我收到了有关数据over here的棘手排序要求的帮助。但是要求已经改变,或者更准确,更广泛。我现在几个小时都在修修补补,但没有成功。我希望 SO 可以帮助我再次解开。

以下是数据库中出现的一些简化样本数据,以及我需要如何订购它。

                **RAW**                                 **DESIRED**

╔════╦════════╦═══════════╦═══════════╗  ╔════╦════════╦═══════════╦═══════════╗
║ id ║ job_id ║ action_id ║ iteration ║  ║ id ║ job_id ║ action_id ║ iteration ║
╠════╬════════╬═══════════╬═══════════╣  ╠════╬════════╬═══════════╬═══════════╣
║  1 ║      1 ║         1 ║         0 ║  ║ 14 ║      6 ║         1 ║         0 ║
║  2 ║      1 ║         2 ║         0 ║  ║ 16 ║      6 ║         2 ║         0 ║
║  3 ║      2 ║         1 ║         0 ║  ║ 12 ║      1 ║         1 ║         1 ║
║  4 ║      3 ║         1 ║         0 ║  ║ 13 ║      1 ║         2 ║         1 ║
║  5 ║      4 ║         1 ║         0 ║  ║ 15 ║      1 ║         3 ║         1 ║
║  6 ║      3 ║         2 ║         0 ║  ║  8 ║      5 ║         1 ║         0 ║
║  7 ║      3 ║         3 ║         0 ║  ║ 10 ║      5 ║         2 ║         0 ║
║  8 ║      5 ║         1 ║         0 ║  ║ 11 ║      5 ║         3 ║         0 ║
║  9 ║      4 ║         2 ║         0 ║  ║  5 ║      4 ║         1 ║         0 ║
║ 10 ║      5 ║         2 ║         0 ║  ║  9 ║      4 ║         2 ║         0 ║
║ 11 ║      5 ║         3 ║         0 ║  ║  4 ║      3 ║         1 ║         0 ║
║ 12 ║      1 ║         1 ║         1 ║  ║  6 ║      3 ║         2 ║         0 ║
║ 13 ║      1 ║         2 ║         1 ║  ║  7 ║      3 ║         3 ║         0 ║
║ 14 ║      6 ║         1 ║         0 ║  ║  3 ║      2 ║         1 ║         0 ║
║ 15 ║      1 ║         3 ║         1 ║  ║  1 ║      1 ║         1 ║         0 ║
║ 16 ║      6 ║         2 ║         0 ║  ║  2 ║      1 ║         2 ║         0 ║
╚════╩════════╩═══════════╩═══════════╝  ╚════╩════════╩═══════════╩═══════════╝
                **EXPLAINED**

╔════╦════════╦═══════════╦═══════════╗
║ id ║ job_id ║ action_id ║ iteration ║
╠════╬════════╬═══════════╬═══════════╣     ORDERED BY:
║ 14 ║      6 ║         1 ║         0 ║
║ 16 ║      6 ║         2 ║         0 ║     The largest id with action_id of 1
╠════╬════════╬═══════════╬═══════════╣     followed by all of the rows with the
║ 12 ║      1 ║         1 ║         1 ║     same job_id and iteration number as
║ 13 ║      1 ║         2 ║         1 ║     the first, ordered by ascending
║ 15 ║      1 ║         3 ║         1 ║     action_id.
╠════╬════════╬═══════════╬═══════════╣
║  8 ║      5 ║         1 ║         0 ║     Then the next largest id with
║ 10 ║      5 ║         2 ║         0 ║     action_id = 1, etc.
║ 11 ║      5 ║         3 ║         0 ║
╠════╬════════╬═══════════╬═══════════╣
║  5 ║      4 ║         1 ║         0 ║
║  9 ║      4 ║         2 ║         0 ║
╠════╬════════╬═══════════╬═══════════╣
║  4 ║      3 ║         1 ║         0 ║
║  6 ║      3 ║         2 ║         0 ║
║  7 ║      3 ║         3 ║         0 ║
╠════╬════════╬═══════════╬═══════════╣
║  3 ║      2 ║         1 ║         0 ║
╠════╬════════╬═══════════╬═══════════╣
║  1 ║      1 ║         1 ║         0 ║
║  2 ║      1 ║         2 ║         0 ║
╚════╩════════╩═══════════╩═══════════╝

我目前正在使用这样的ORDER BY

SELECT *
FROM reports as r
ORDER BY
    FIND_IN_SET(r.job_id, ( SELECT GROUP_CONCAT(job_id ORDER BY id DESC)
                            FROM reports
                            WHERE action_id = 1)),
    r.action_id

但它并没有考虑到迭代。我无法看到我在哪里可以适应这种逻辑。任何人都可以提供任何帮助吗?

非常感谢!

1 个答案:

答案 0 :(得分:1)

有趣但不那么复杂..只需要使用自联接和子选择。另外我认为订单现在更容易阅读。

http://sqlfiddle.com/#!2/7f9d2/1/0

SELECT r.id, r.job_Id, r.action_id, r.iteration,  r2.mid, r2.job_Id
FROM raw r
INNER JOIN (SELECT max(ID) mID, Job_ID, iteration 
           FROM raw 
           WHERE action_ID=1 
           GROUP BY Job_Id, iteration) r2
 on R.Job_Id = R2.Job_ID
 and R.Iteration = R2.iteration
ORDER BY r2.mid desc, iteration, r.action_Id

这里的关键是首先将您概述的群组放在一起。通过执行子选择以获取每个组中的最大ID,然后将这些组连接回基本集,然后根据自联接/子查询中的最大ID应用排序...以及您的其他逻辑...您得到你所追求的。

从集合的角度考虑SQL,这种排序变得更容易。

您需要一组数据来定义每个组的组和最大值(我的内联视图)。那么你需要根据子集中的最大值,迭代,然后来自主集的动作进行排序。

我使用了一个左连接,以防一些数据在我移植到小提琴时搞砸了,但内心应该 工作也一样。