我有一个场景,我必须显示某个流程的总注册人数。有两种状态,正在进行和完成。该人员可以多次注册该流程,并且每次我们在名为process_people的表中跟踪该人员。人们记录的每个流程可能处于流程的不同步骤。
假设某人A进入过程A并完成了该过程,而同一个人再次进入并成为该过程的一部分(进行中)。
我需要获得唯一的总注册人数,我可以使用以下方法获得该数字,
unique_count = ProcessPerson.where(status: %[completed inprogress]).select(:person_id).distinct.count
要求是显示唯一的活跃人数,这也应该是唯一的人数。如果一个人完成了相同的过程并且在同一过程中进行了进度,则意味着我们需要在活跃人员计数中跳过它们。正在进行的过程且之前未完成同一过程的人数是预期结果。
注册总人数=唯一(进步中的人+已完成的人)
活跃的人=独特的(谁在进行中并且之前未完成相同的过程)
有人可以帮我吗?
答案 0 :(得分:1)
您可以尝试以下查询:
SELECT grouped_process_people.*
FROM (
SELECT ordered_process_people.*
FROM (
SELECT process_id, people_id, status
FROM scratch.process_people
ORDER BY (status = 'completed') DESC , status /* (1) */
) as ordered_process_people
GROUP BY process_id, people_id /* (2) */
) as grouped_process_people
WHERE status <> 'completed'; /* (3) */
该SQL中发生了什么(使用子查询旁边的数字),说您的表如下所示:
+----+------------+-----------+------------+
| id | process_id | people_id | status |
+----+------------+-----------+------------+
| 1 | 11 | 21 | inprogress |
| 2 | 11 | 21 | completed |
| 3 | 11 | 21 | inprogress |
| 4 | 12 | 21 | inprogress |
| 5 | 12 | 21 | inprogress |
| 6 | 12 | 21 | inprogress |
| 7 | 13 | 23 | inprogress |
| 8 | 13 | 23 | completed |
+----+------------+-----------+------------+
+------------+-----------+------------+
| process_id | people_id | status |
+------------+-----------+------------+
| 11 | 21 | completed |
| 13 | 23 | completed |
| 11 | 21 | inprogress |
| 11 | 21 | inprogress |
| 12 | 21 | inprogress |
| 12 | 21 | inprogress |
| 12 | 21 | inprogress |
| 13 | 23 | inprogress |
+------------+-----------+------------+
process_id
和people_id
分组,以便仅选择这些对的唯一组合,并标记状态为已完成的对。+------------+-----------+------------+
| process_id | people_id | status |
+------------+-----------+------------+
| 11 | 21 | completed |
| 12 | 21 | inprogress |
| 13 | 23 | completed |
+------------+-----------+------------+
+------------+-----------+------------+
| process_id | people_id | status |
+------------+-----------+------------+
| 12 | 21 | inprogress |
+------------+-----------+------------+
运行此查询的方式是将其存储为字符串,例如,如果将其存储在名为active_people_process_query
的变量中,则它将像这样运行:
ProcessPerson.find_by_sql(active_people_process_query)
答案 1 :(得分:0)
我认为这不能一步完成(一个查询),但是我的想法是:
首先,我们按person_id和process_id分组
step_1 = ProcessPerson.all.select(:person_id, :process_id, :status).group_by{ |pp| [pp.person_id, pp.process_id]}
结果:
{
[5, 5]=> [
{person_id: 5, process_id: 5, status: "completed"},
{person_id: 5, process_id: 5, status: "inprogress"}
],
[4, 1]=>[
{person_id: 4, process_id: 1, status: "completed"},
{person_id: 4, process_id: 1, status: "inprogress"}
],
[6, 5]=>[
{person_id: 6, process_id: 5, status: "completed"}
],
[2, 5]=>[
{person_id: 2, process_id: 5, status: "completed"}
],
[6, 2]=>[
{person_id: 6, process_id: 2, status: "inprogress"}
],
[2, 2]=>[
{person_id: 2, process_id: 2, status: "completed"}
],
[5, 3]=>[
{person_id: 5, process_id: 3, status: "inprogress"}
],
[3, 4]=>[
{person_id: 3, process_id: 4, status: "completed"}
]
}
然后我们选择进行中且尚未完成过程的任何组
step_2 = step_1.filter{ |k, v| v.any? {|h| h[:status] == "inprogress" } && !v.any? {|h| h[:status] == "completed" } }
结果:
{
[6, 2]=>[
{person_id: 6, process_id: 2, status: "inprogress"}
],
[5, 3]=>[
{person_id: 5, process_id: 3, status: "inprogress"}
]
}
然后我们计算结果
step_3 = step_2.count
结果:
2