MySQL - 按父位置和子位置排序

时间:2015-10-01 10:07:34

标签: mysql sql

我有以下查询

SELECT process.*
FROM (`process`)
WHERE `company_id` = '1' AND `status` = '1'                                                        
ORDER BY COALESCE(`process`.`parent_id`, `process`.`id`), `process`.`parent_id` IS NOT NULL asc, `process`.`position` asc

请参阅SQLFiddie了解表,数据和查询

http://sqlfiddle.com/#!9/d50ba/2

查询对子进程的位置编号进行了正确的排序。 但是我还需要Main进程按其位置编号(两个ASC)排序。

修改 op IDS的顺序应为7,1,16,41,42,6,40 首先应该通过ASC在每个主要流程订单中对所有主要流程进行排序,并在位置ASC上对所有属于子流程的流程进行排序

是:

╔═════╦════════════╦═════════════╦════════════════╦═══════════════════╦═════════════╦═══════════════╦═══════════╦═════════════╦═══════════╦═════════╦════════════════════════════╗
║ id  ║ parent_id  ║ company_id  ║ department_id  ║       name        ║ user_score  ║ user_comment  ║ ic_score  ║ ic_comment  ║ position  ║ status  ║        date_created        ║
╠═════╬════════════╬═════════════╬════════════════╬═══════════════════╬═════════════╬═══════════════╬═══════════╬═════════════╬═══════════╬═════════╬════════════════════════════╣
║  1  ║ (null)     ║          1  ║             3  ║ Main Process 1    ║          0  ║ (null)        ║        0  ║ (null)      ║        2  ║      1  ║ February, 02 2015 21:04:03 ║
║ 16  ║ 1          ║          1  ║             3  ║ Sub Process 1, 1  ║          0  ║ (null)        ║        0  ║ (null)      ║        1  ║      1  ║ February, 02 2015 21:14:34 ║
║ 41  ║ 1          ║          1  ║             3  ║ Sub Process 4, 1  ║          0  ║ (null)        ║        0  ║ (null)      ║        9  ║      1  ║ February, 09 2015 10:06:40 ║
║  6  ║ (null)     ║          1  ║             3  ║ Main Process 2    ║          0  ║ (null)        ║        0  ║ (null)      ║        8  ║      1  ║ February, 02 2015 21:08:53 ║
║  7  ║ (null)     ║          1  ║             3  ║ Main Process 3    ║          0  ║ (null)        ║        0  ║ (null)      ║        1  ║      1  ║ February, 02 2015 21:09:08 ║
║ 40  ║ (null)     ║          1  ║             3  ║ Main Process 2    ║          0  ║ (null)        ║        0  ║ (null)      ║       16  ║      1  ║ February, 09 2015 10:05:36 ║
║ 42  ║ (null)     ║          1  ║             3  ║ Main Process 3    ║          0  ║ (null)        ║        0  ║ (null)      ║        7  ║      1  ║ February, 09 2015 10:14:36 ║
╚═════╩════════════╩═════════════╩════════════════╩═══════════════════╩═════════════╩═══════════════╩═══════════╩═════════════╩═══════════╩═════════╩════════════════════════════╝

期望的输出:

╔═════╦════════════╦═════════════╦════════════════╦═══════════════════╦═════════════╦═══════════════╦═══════════╦═════════════╦═══════════╦═════════╦════════════════════════════╗
║ id  ║ parent_id  ║ company_id  ║ department_id  ║       name        ║ user_score  ║ user_comment  ║ ic_score  ║ ic_comment  ║ position  ║ status  ║        date_created        ║
╠═════╬════════════╬═════════════╬════════════════╬═══════════════════╬═════════════╬═══════════════╬═══════════╬═════════════╬═══════════╬═════════╬════════════════════════════╣
║  7  ║ (null)     ║          1  ║             3  ║ Main Process 3    ║          0  ║ (null)        ║        0  ║ (null)      ║        1  ║      1  ║ February, 02 2015 21:09:08 ║
║  1  ║ (null)     ║          1  ║             3  ║ Main Process 1    ║          0  ║ (null)        ║        0  ║ (null)      ║        2  ║      1  ║ February, 02 2015 21:04:03 ║
║ 16  ║ 1          ║          1  ║             3  ║ Sub Process 1, 1  ║          0  ║ (null)        ║        0  ║ (null)      ║        1  ║      1  ║ February, 02 2015 21:14:34 ║
║ 41  ║ 1          ║          1  ║             3  ║ Sub Process 4, 1  ║          0  ║ (null)        ║        0  ║ (null)      ║        9  ║      1  ║ February, 09 2015 10:06:40 ║
║ 42  ║ (null)     ║          1  ║             3  ║ Main Process 3    ║          0  ║ (null)        ║        0  ║ (null)      ║        7  ║      1  ║ February, 09 2015 10:14:36 ║
║  6  ║ (null)     ║          1  ║             3  ║ Main Process 2    ║          0  ║ (null)        ║        0  ║ (null)      ║        8  ║      1  ║ February, 02 2015 21:08:53 ║
║ 40  ║ (null)     ║          1  ║             3  ║ Main Process 2    ║          0  ║ (null)        ║        0  ║ (null)      ║       16  ║      1  ║ February, 09 2015 10:05:36 ║
╚═════╩════════════╩═════════════╩════════════════╩═══════════════════╩═════════════╩═══════════════╩═══════════╩═════════════╩═══════════╩═════════╩════════════════════════════╝

2 个答案:

答案 0 :(得分:1)

这是可能的,但是你需要父进程在子进程的行中的位置。为此,您需要自行加入流程表。为了实现所需的排序,我使用了位移。这将产生BIGINT,其中前32位反转为父项的位置,后32位保留给子项的位置。在父行的情况下,它们自己的位置用作前32位的位置,最后32位设置为0.

这导致以下查询:

SELECT `process`.*
FROM `process`
LEFT JOIN `process` AS `processParent` ON `processParent`.`id` = `process`.`parent_id`
WHERE `process`.`company_id` = '1' AND `process`.`status` = '1'                                                        
ORDER BY 
    (IF(`process`.`parent_id` IS NULL, `process`.`position`, `processParent`.`position`) << 32)
    + IF(`process`.`parent_id` IS NULL, 0, `process`.`position`) ASC;

编辑:请记住,只有当一个进程是父进程或子进程时,它才有效,但它不能同时运行。

答案 1 :(得分:1)

我不会为此使用位移,似乎不必要地复杂。您希望先按父位置排序,然后再按位置排序:

   SELECT p.*
     FROM `process` p
LEFT JOIN `process` parent 
       ON parent.id = p.parent_id
    WHERE p.company_id = '1' AND p.status = '1'
 ORDER BY COALESCE(parent.position, p.position), 
          parent.position IS NULL DESC,
          p.position