MySQL – Pivot table per day

Consider the following schema:

CREATE TABLE IF NOT EXISTS `tblappointment` (
  `app_id` int(6),
  `app_date` date,
  `app_price` int(6),
  `app_price_in` int(6),
  `app_price_out` int(6),
  PRIMARY KEY (`app_id`)
) DEFAULT CHARSET=utf8;

INSERT INTO `tblappointment` (`app_id`, `app_date`, `app_price`, `app_price_in`, `app_price_out`) VALUES
  ('1', '2021/03/20', '50', '80', '30'),
  ('2', '2021/05/10', '30', '20', '50'),
  ('3', '2021/01/14', '20', '60', '10'),
  ('4', '2021/04/05', '20', '20', '20'),
  ('5', '2020/07/08', '30', '70', '10'),
  ('6', '2019/08/28', '40', '80', '40'),
  ('7', '2020/12/11', '50', '10', '60'),
  ('8', '2018/10/19', '10', '20', '30'),
  ('9', '2019/01/10', '20', '30', '20'),
  ('10', '2021/12/13', '10', '20', '20');

I have the following MySQL query which i am getting the sums per month (columns) and per year (rows).

My output now, look like this:

+------+-----+-----+-----+-----+-----+-----+-------+
| Year | 1   | 2   | 3   | ... | 11  | 12  | Total |
+------+-----+-----+-----+-----+-----+-----+-------+
| 2021 | 200 | 250 | 150 |     | 100 | 200 | 1300  |
+------+-----+-----+-----+-----+-----+-----+-------+
| 2020 | 100 | 150 | 200 |     | 100 | 100 | 1700  |
+------+-----+-----+-----+-----+-----+-----+-------+

I would like to have per days(columns) and per year, month(rows).

Desire Output would like to look like this:

+------+--------+----+----+----+-----+----+----+-------+
| Year | Months | 1  | 2  | 3  | ... | 30 | 31 | Total |
+------+--------+----+----+----+-----+----+----+-------+
| 2021 | 2      | 50 | 20 | 10 |     | 20 | 10 | 350   |
+------+--------+----+----+----+-----+----+----+-------+
| 2021 | 1      | 10 | 0  | 20 |     | 10 | 20 | 130   |
+------+--------+----+----+----+-----+----+----+-------+
| 2020 | 12     | 20 | 10 | 20 |     | 10 | 10 | 240   |
+------+--------+----+----+----+-----+----+----+-------+

My MySQL code so far is:

select 
    y.yr,
    d.details,
    sum(case when month(app_date) = 1  then val else 0 end) month_01,
    sum(case when month(app_date) = 2  then val else 0 end) month_02,
    ...
    sum(case when month(app_date) = 12 then val else 0 end) month_12,
    sum(case when month(app_date) > 0  then val else 0 end) total
FROM (
    SELECT '101' dorder, 'balance' details UNION ALL 
    SELECT '102' dorder, 'in' details UNION ALL
    SELECT '103' dorder, 'out' details
) d cross join (
    SELECT distinct year(app_date) yr
    FROM tblappointment 
) y    
left join (  
        select app_date, COALESCE(app_price, 0) val, 'balance' details from tblappointment 
    union all
        select app_date, COALESCE(app_price_in, 0) val, 'in' details from tblappointment 
    union all
        select app_date, COALESCE(app_price_out, 0) val, 'out' details from tblappointment 
) t on year(t.app_date) = y.yr and t.details = d.details
group by y.yr, d.details
order by y.yr desc, d.dorder;

My build schema and sample data for testing:

Build Schema Demo Page

Answer

Find it after some tests:

    select 
    y.yr,
    y.mth,
    d.details,
    sum(case when day(app_date) = 1  then val else 0 end) day_01,
    sum(case when day(app_date) = 2  then val else 0 end) day_02,
    sum(case when day(app_date) = 3  then val else 0 end) day_03,
    ...
    sum(case when day(app_date) = 31 then val else 0 end) day_31,
    sum(case when day(app_date) > 0  then val else 0 end) total
FROM (
    SELECT '101' dorder, 'balance' details UNION ALL 
    SELECT '102' dorder, 'in' details UNION ALL
    SELECT '103' dorder, 'out' details
) d cross join (
    SELECT distinct year(app_date) yr, month(app_date) mth
    FROM tblappointment 
) y    
left join (  
        select app_date, COALESCE(app_price, 0) val, 'balance' details from tblappointment 
    union all
        select app_date, COALESCE(app_price_in, 0) val, 'in' details from tblappointment 
    union all
        select app_date, COALESCE(app_price_out, 0) val, 'out' details from tblappointment 
) t on year(t.app_date) = y.yr and month(t.app_date) = y.mth and t.details = d.details
group by y.yr, y.mth, d.details
order by y.yr desc, y.mth desc, d.dorder;