Вы можете попробовать этот запрос:
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)