我有以下查询
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 ║
╚═════╩════════════╩═════════════╩════════════════╩═══════════════════╩═════════════╩═══════════════╩═══════════╩═════════════╩═══════════╩═════════╩════════════════════════════╝
答案 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