Hmmm. Jika saya mengartikan "empat kuartal terakhir" sebagai "empat kuartal terakhir yang ada dalam data", maka inilah salah satu metodenya.
Pertama, Anda bisa mendapatkan empat kuartal dengan melakukan:
select distinct p_year, p_quarter
from production p
order by p_year desc, p_quarter desc
limit 4;
Anda dapat menghitungnya menggunakan variabel:
select p_year, p_quarter, (@rn := @rn + 1) as enum
from (select distinct p_year, p_quarter
from production p
order by p_year desc, p_quarter desc
limit 4
) p cross join
(select @rn := 0) params
Kemudian, Anda dapat menggunakan ini dalam kueri untuk memutar data:
select p.person_id,
sum(case when seqnum = 1 then num else 0 end) as num_quarter_1,
sum(case when seqnum = 2 then num else 0 end) as num_quarter_2,
sum(case when seqnum = 3 then num else 0 end) as num_quarter_3,
sum(case when seqnum = 4 then num else 0 end) as num_quarter_4
from production p join
(select p_year, p_quarter, (@rn := @rn + 1) as seqnum
from (select distinct p_year, p_quarter
from production p
order by p_year desc, p_quarter desc
limit 4
) p cross join
(select @rn := 0) params
) yq
using (p_year, p_quarter)
group by p.person_id;
EDIT:
Jika Anda menentukan kuartal berdasarkan kuartal saat ini, Anda dapat melakukan sesuatu yang sangat mirip:
select p.person_id,
sum(case when seqnum = 1 then num else 0 end) as num_quarter_1,
sum(case when seqnum = 2 then num else 0 end) as num_quarter_2,
sum(case when seqnum = 3 then num else 0 end) as num_quarter_3,
sum(case when seqnum = 4 then num else 0 end) as num_quarter_4
from production p join
(select year(curdate()) as p_year, quarter(curdate()) as p_quarter, 1 as seqnum union all
select year(curdate() - interval 1 quarter) as p_year, month(curdate() - interval 1 quarter) as p_quarter, 2 as seqnum union all
select year(curdate() - interval 2 quarter) as p_year, month(curdate() - interval 2 quarter) as p_quarter, 3 as seqnum union all
select year(curdate() - interval 2 quarter) as p_year, month(curdate() - interval 3 quarter) as p_quarter, 4 as seqnum
) yq
using (p_year, p_quarter)
group by p.person_id;
Ada pendekatan lain, seperti:
select person_id,
sum(case when year(curdate()) = p_year and quarter(curdate()) = p_quarter
then num else 0
end) as num_quarter_1,
sum(case when year(curdate() - interval 1 quarter) = p_year and quarter(curdate() - interval 1 quarter) = p_quarter
then num else 0
end) as num_quarter_2,
sum(case when year(curdate() - interval 2 quarter) = p_year and quarter(curdate() - interval 2 quarter) = p_quarter
then num else 0
end) as num_quarter_3,
sum(case when year(curdate() - interval 3 quarter) = p_year and quarter(curdate() - interval 3 quarter) = p_quarter
then num else 0
end) as num_quarter_4
from production p
group by person_id;