我有一个场景,我必须显示一个过程的总登记人数。进展和完成有两种状态。此人可以多次注册该流程,并且每次我们在名为process_people的表中跟踪该人员。人们记录的每个过程可能处于一个过程的不同步骤。
让我们说A人进入流程A并完成流程,同一个人再次进入并成为流程的一部分(正在进行中)。
我需要的是我需要获得独特的总登记人数,我可以使用下面的内容,
unique_count = ProcessPerson.where(status: %[completed inprogress]).select(:person_id).distinct.count
要求是显示唯一的活跃人数,这也应该是唯一计数。如果一个人完成相同的过程并且在同一过程中进行,则意味着我们需要在活跃的人数中跳过它们。正在进行过程并且之前未完成相同过程的人数是预期结果。
总登记人数=独特(进步人员+已完成人员)
活跃的人=唯一(谁在进行中,之前没有完成相同的过程)
谁能帮我这个?
你可以尝试这个查询:
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)
我不认为这可以一步完成(一个查询),但我想到的是:
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"}
]
}