Tôi nghĩ điều này làm được.
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
Kết quả từ dữ liệu bạn cung cấp là:
+---------+-----------------+------------+-----------+
| 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 |
+---------+-----------------+------------+-----------+
Tôi quen thuộc hơn với T-SQL, nơi tôi sử dụng hàm cửa sổ row_number (). Ý tưởng là để trường row_number hiển thị xếp hạng của mỗi hàng về việc đó là hành động gần đây nhất (giá trị 1), gần đây nhất thứ hai (giá trị 2), v.v. cho mỗi tác vụ. Hành động gần đây nhất cho mỗi nhiệm vụ kết thúc với row_number là 1, vì vậy bạn có thể lấy chúng ra bằng cách lọc trên row_number =1 từ latest_action
này truy vấn con.
Bởi vì latest_action
truy vấn con được chạy tổng thể một lần, không phải mỗi hàng một lần, nó không có nhiều tác dụng. Thật không may, tôi không thể hứa rằng toàn bộ cài đặt / tăng dần biến không ảnh hưởng nhiều đến hiệu suất, đây là lần đầu tiên tôi sử dụng logic này trong MySQL, tôi không biết nó hoạt động như thế nào.
Logic về cách tái tạo chức năng row_number () của T-SQL đến từ đây: ROW_NUMBER () trong MySQL