Ik denk dat dit het doet.
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
De resultaten van de door u verstrekte gegevens zijn:
+---------+-----------------+------------+-----------+
| 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 |
+---------+-----------------+------------+-----------+
Ik ben meer bekend met T-SQL, waar ik de vensterfunctie row_number() zou gebruiken. Het idee is om het veld row_number een rangorde van elke rij te laten zien in termen van of het de meest recente (waarde 1), op één na meest recente (waarde 2) enz. actie is voor elke taak. De meest recente actie voor elke taak eindigt met een row_number van 1, dus je kunt deze eruit halen door te filteren op row_number =1 van deze latest_action
subquery.
Omdat de latest_action
subquery wordt één keer in het algemeen uitgevoerd, niet één keer per rij, het is niet echt een prestatiehit. Helaas kan ik niet beloven dat het hele variabele instellen / verhogen niet echt een prestatiehit is, dit is de eerste keer dat ik deze logica in MySQL gebruik, ik weet niet hoe goed het is.
De logica voor het reproduceren van de row_number()-functionaliteit van T-SQL kwam hier vandaan: ROW_NUMBER() in MySQL