Penso che questo lo faccia.
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
I risultati dai dati che hai fornito sono:
+---------+-----------------+------------+-----------+
| 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 |
+---------+-----------------+------------+-----------+
Ho più familiarità con T-SQL, dove userei la funzione della finestra row_number(). L'idea è che il campo numero_riga mostri una classifica di ogni riga in termini di azione più recente (valore 1), seconda più recente (valore 2) ecc. per ogni attività. L'azione più recente per ogni attività finisce con un numero_riga pari a 1, quindi puoi eliminarli filtrando numero_riga =1 da questo latest_action
sottoquery.
Perché l'latest_action
la sottoquery viene eseguita una volta nel complesso, non una volta per riga, non è un gran colpo di prestazioni. Sfortunatamente, non posso promettere che l'intera cosa dell'impostazione/incremento delle variabili non sia un gran successo in termini di prestazioni, questa è la prima volta che utilizzo questa logica in MySQL, non so quanto sia performante.
La logica su come riprodurre la funzionalità row_number() di T-SQL deriva da qui: ROW_NUMBER() in MySQL