By using db<>fiddle, you agree to license everything you submit by Creative Commons CC0.
CREATE TABLE test (id SERIAL PRIMARY KEY,
datefrom DATE,
datetill DATE,
amount DECIMAL(10, 2));
INSERT INTO test (datefrom, datetill, amount) VALUES
('2020-01-10','2020-02-15',1000),
('2019-01-10','2020-02-15',1000);
SELECT * FROM test;
Records: 2 Duplicates: 0 Warnings: 0
id | datefrom | datetill | amount |
---|---|---|---|
1 | 2020-01-10 | 2020-02-15 | 1000.00 |
2 | 2019-01-10 | 2020-02-15 | 1000.00 |
SELECT id,
datefrom,
datetill,
amount,
monthstart,
monthfinish,
amount * (DATEDIFF(LEAST(datetill, monthfinish), GREATEST(datefrom, monthstart)) + 1) / (DATEDIFF(datetill, datefrom) + 1) monthamount
FROM ( SELECT test.*,
(test.datefrom - INTERVAL DAY(test.datefrom) - 1 DAY) + INTERVAL numbers.num MONTH monthstart,
LAST_DAY((test.datefrom - INTERVAL DAY(test.datefrom) - 1 DAY) + INTERVAL numbers.num MONTH) monthfinish
FROM test
JOIN ( SELECT t1.num*10+t2.num num
FROM (SELECT 0 num UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1
JOIN (SELECT 0 num UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2
) numbers
HAVING monthstart <= test.datetill
AND monthfinish >= test.datefrom
) subquery
ORDER BY id, monthstart;
id | datefrom | datetill | amount | monthstart | monthfinish | monthamount |
---|---|---|---|---|---|---|
1 | 2020-01-10 | 2020-02-15 | 1000.00 | 2020-01-01 | 2020-01-31 | 594.594595 |
1 | 2020-01-10 | 2020-02-15 | 1000.00 | 2020-02-01 | 2020-02-29 | 405.405405 |
2 | 2019-01-10 | 2020-02-15 | 1000.00 | 2019-01-01 | 2019-01-31 | 54.726368 |
2 | 2019-01-10 | 2020-02-15 | 1000.00 | 2019-02-01 | 2019-02-28 | 69.651741 |
2 | 2019-01-10 | 2020-02-15 | 1000.00 | 2019-03-01 | 2019-03-31 | 77.114428 |
2 | 2019-01-10 | 2020-02-15 | 1000.00 | 2019-04-01 | 2019-04-30 | 74.626866 |
2 | 2019-01-10 | 2020-02-15 | 1000.00 | 2019-05-01 | 2019-05-31 | 77.114428 |
2 | 2019-01-10 | 2020-02-15 | 1000.00 | 2019-06-01 | 2019-06-30 | 74.626866 |
2 | 2019-01-10 | 2020-02-15 | 1000.00 | 2019-07-01 | 2019-07-31 | 77.114428 |
2 | 2019-01-10 | 2020-02-15 | 1000.00 | 2019-08-01 | 2019-08-31 | 77.114428 |
2 | 2019-01-10 | 2020-02-15 | 1000.00 | 2019-09-01 | 2019-09-30 | 74.626866 |
2 | 2019-01-10 | 2020-02-15 | 1000.00 | 2019-10-01 | 2019-10-31 | 77.114428 |
2 | 2019-01-10 | 2020-02-15 | 1000.00 | 2019-11-01 | 2019-11-30 | 74.626866 |
2 | 2019-01-10 | 2020-02-15 | 1000.00 | 2019-12-01 | 2019-12-31 | 77.114428 |
2 | 2019-01-10 | 2020-02-15 | 1000.00 | 2020-01-01 | 2020-01-31 | 77.114428 |
2 | 2019-01-10 | 2020-02-15 | 1000.00 | 2020-02-01 | 2020-02-29 | 37.313433 |