Jag tror att det här 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
Resultaten från de uppgifter du angav är:
+---------+-----------------+------------+-----------+
| 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 |
+---------+-----------------+------------+-----------+
Jag är mer bekant med T-SQL, där jag skulle använda fönsterfunktionen row_number(). Tanken är att fältet radnummer ska visa en rangordning av varje rad i termer av om det är den senaste (värde 1), näst senaste (värde 2) etc. åtgärd för varje uppgift. Den senaste åtgärden för varje uppgift slutar med radnummer 1, så du kan få ut dessa genom att filtrera på radnummer =1 från denna latest_action
underfråga.
Eftersom latest_action
subquery körs en gång totalt, inte en gång per rad, det är inte mycket av en prestandaträff. Tyvärr kan jag inte lova att hela grejen med variabelinställning/ökning inte är mycket av en prestandahit, det här är första gången jag har använt den här logiken i MySQL, jag vet inte hur prestanda den är.
Logiken för hur man reproducerar T-SQL:s row_number() funktionalitet kom härifrån: ROW_NUMBER() i MySQL