Jeg tror, det gør det.
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
Resultaterne fra de data, du har angivet, er:
+---------+-----------------+------------+-----------+
| 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 |
+---------+-----------------+------------+-----------+
Jeg er mere bekendt med T-SQL, hvor jeg ville bruge row_number() vinduesfunktionen. Ideen er at få feltet rækkenummer til at vise en rangering af hver række i forhold til, om det er den seneste (værdi 1), næstnyeste (værdi 2) osv. handling for hver opgave. Den seneste handling for hver opgave ender med et rækkenummer på 1, så du kan få disse ud ved at filtrere på rækkenummer =1 fra denne latest_action
underforespørgsel.
Fordi latest_action
underforespørgsel køres én gang samlet set, ikke én gang pr. række, det er ikke meget af et præstationshit. Desværre kan jeg ikke love, at hele den variable indstilling/forøgelse ikke er et stort præstationshit, det er første gang, jeg har brugt denne logik i MySQL, jeg ved ikke, hvor effektiv den er.
Logikken for, hvordan man gengiver T-SQL's row_number() funktionalitet kom herfra: ROW_NUMBER() i MySQL