Myślę, że to wystarczy.
select
t_task.task_id,
t_task.task_name,
latest_action.act_date,
IFNULL(t_act_d.act_name, 'Pending') as act_name
from
t_task
left outer join (
select
@row_num := IF(@prev_value=concat_ws('', t_act.task_id),@row_num+1, 1) as row_number,
t_act.task_id,
t_act.act_id,
t_act.act_date,
@prev_value := concat_ws('', t_act.task_id) as z
from
t_act,
(select @row_num := 1) x,
(select @prev_value := '') y
order by
t_act.task_id,
t_act.act_date desc
) as latest_action on
t_task.task_id = latest_action.task_id
left outer join t_act_d on
latest_action.act_id = t_act_d.act_id
where
latest_action.row_number = 1 or
latest_action.row_number is null
order by
case when latest_action.act_date is null then '9999-01-01' else latest_action.act_date end
Wyniki z podanych przez Ciebie danych są następujące:
+---------+-----------------+------------+-----------+
| task_id | task_name | act_date | act_name |
+---------+-----------------+------------+-----------+
| A1 | PC Proc | 2017-07-17 | Execution |
| A2 | Printer Proc | 2017-07-21 | Surveying |
| A3 | Stationery Proc | NULL | Pending |
+---------+-----------------+------------+-----------+
Jestem bardziej zaznajomiony z T-SQL, w którym użyłbym funkcji okna row_number(). Pomysł polega na tym, aby pole row_number pokazywało ranking każdego wiersza pod względem tego, czy jest to najnowsza (wartość 1), druga najnowsza (wartość 2) itd. dla każdego zadania. Najnowsza akcja dla każdego zadania kończy się numerem row_number równym 1, więc możesz je uzyskać, filtrując według row_number =1 z tego latest_action
podzapytanie.
Ponieważ latest_action
podzapytanie jest uruchamiane raz ogólnie, nie raz na wiersz, nie jest to duży spadek wydajności. Niestety, nie mogę obiecać, że całe ustawianie / zwiększanie zmiennej nie jest zbyt dużym spadkiem wydajności, po raz pierwszy użyłem tej logiki w MySQL, nie wiem, jaka jest wydajna.
Logika, jak odtworzyć funkcjonalność row_number() w T-SQL, pochodzi stąd: ROW_NUMBER() w MySQL