Considering following test data:
CREATE TABLE products_su ( country varchar(2), intprd varchar(20), period date, su int ); INSERT INTO products_su (country, intprd, "period", su) VALUES('GL', 'med', '2024-02-01', 7); INSERT INTO products_su (country, intprd, "period", su) VALUES('GL', 'med', '2024-03-01', 15); INSERT INTO products_su (country, intprd, "period", su) VALUES('GL', 'med', '2024-04-01', 35); INSERT INTO products_su (country, intprd, "period", su) VALUES('GL', 'med', '2024-05-01', 105); INSERT INTO products_su (country, intprd, "period", su) VALUES('GL', 'med', '2024-06-01', 140); INSERT INTO products_su (country, intprd, "period", su) VALUES('GL', 'med', '2024-07-01', 180); INSERT INTO products_su (country, intprd, "period", su) VALUES('GL', 'med', '2024-08-01', 261); INSERT INTO products_su (country, intprd, "period", su) VALUES('GL', 'med', '2024-09-01', 211); INSERT INTO products_su (country, intprd, "period", su) VALUES('GL', 'med', '2024-10-01', 187); INSERT INTO products_su (country, intprd, "period", su) VALUES('GL', 'med', '2024-11-01', 318); INSERT INTO products_su (country, intprd, "period", su) VALUES('GL', 'med', '2024-12-01', 208); COMMIT; I need to create a SQL query to obtain the results given within below spreadsheet, which also contains formulas that had to be translated into query:
https://docs.google.com/spreadsheets/d/13jYM_jVp9SR0Kc9putPNfIzc9uRpIr847FcYjJ426zQ/edit?gid=0#gid=0
The logic for some of the fields is changing after 6 months and stays for month 7+.
A recursive logic needs to be used in here.
My attempts are good for first 6 months, but then I fail:
WITH RECURSIVE su AS ( SELECT country, period, su::FLOAT AS su, ROW_NUMBER() OVER (PARTITION BY country ORDER BY period) - 1 AS rn FROM products_su ), roll ( country, rn, period, tsu, rep_pat, new_pat, tpe, peq, np_0, np_1, np_2, np_3, np_4, np_5, np_6, np_7, np_8, np_9, np_10, np_11, np_12, np_13 ) AS ( -- Anchor (first month) SELECT country, rn, period, su, CAST(0.0 AS FLOAT), ROUND(su / 4.0, 4), ROUND(su / 4.0, 4), CAST(NULL AS FLOAT), ROUND(su / 4.0, 4), CAST(0.0 AS FLOAT), CAST(0.0 AS FLOAT), CAST(0.0 AS FLOAT), CAST(0.0 AS FLOAT), CAST(0.0 AS FLOAT), CAST(0.0 AS FLOAT), CAST(0.0 AS FLOAT), CAST(0.0 AS FLOAT), CAST(0.0 AS FLOAT), CAST(0.0 AS FLOAT), CAST(0.0 AS FLOAT), CAST(0.0 AS FLOAT), CAST(0.0 AS FLOAT) FROM su WHERE rn = 0 UNION ALL -- Recursive rows SELECT s.country, s.rn, s.period, s.su, CASE WHEN s.rn < 6 THEN 0.0 ELSE ROUND((r.np_1 + r.np_2 + r.np_3) / 3.0, 4) END, CASE WHEN s.rn < 6 THEN ROUND(s.su / 4.0, 4) ELSE ROUND((s.su - ((r.np_1 + r.np_2 + r.np_3) / 3.0 * 6.0)) / 6.0, 4) END, CASE WHEN s.rn < 6 THEN ROUND(s.su / 4.0, 4) ELSE ROUND((s.su - ((r.np_1 + r.np_2 + r.np_3) / 3.0 * 6.0)) / 6.0, 4) END, CASE WHEN s.rn < 13 THEN NULL ELSE ROUND(( CASE WHEN s.rn < 6 THEN ROUND(s.su / 4.0, 4) ELSE ROUND((s.su - ((r.np_1 + r.np_2 + r.np_3) / 3.0 * 6.0)) / 6.0, 4) END + r.np_0 + r.np_1 + r.np_2 + r.np_3 + r.np_4 + r.np_5 + r.np_6 + r.np_7 + r.np_8 + r.np_9 + r.np_10 + r.np_11 + r.np_12 ), 4) END, -- Shift new_pat history CASE WHEN s.rn < 6 THEN ROUND(s.su / 4.0, 4) ELSE ROUND((s.su - ((r.np_1 + r.np_2 + r.np_3) / 3.0 * 6.0)) / 6.0, 4) END, r.np_0, r.np_1, r.np_2, r.np_3, r.np_4, r.np_5, r.np_6, r.np_7, r.np_8, r.np_9, r.np_10, r.np_11, r.np_12 FROM roll r JOIN su s ON s.country = r.country AND s.rn = r.rn + 1 ) SELECT country, period, ROUND(tsu, 2) AS su, tpe, rep_pat, new_pat, peq FROM roll ORDER BY country, period; I will appreciate help on this one.