I have sales data at the start of every month in a quarter.
Example: For 22-Q1 quarter, I have sales on 3 dates (1st Jan, 1st Feb and 1st March)
Date | Country | Region | Sales |
---|---|---|---|
01/01/2022 | UK | EMEA | 100,000 |
02/01/2022 | UK | EMEA | 170,000 |
03/01/2022 | UK | EMEA | 120,000 |
01/01/2022 | US | AMS | 90,000 |
02/01/2022 | US | AMS | 110,000 |
03/01/2022 | US | AMS | 160,000 |
My requirement is to extrapolate the Sales data between the 2 given dates based on difference between the 2 dates and concatenate them to the same table.
For example for 2nd Jan, I calculate the date difference between 1st Jan and 1st Feb, which is 31 days and increment Sales amount by (1/31) and for 3rd Jan, I increment Sales amount by (2/31).. so on until 31st Jan.
After the month change, the date difference needs to be recalculated between 1st Feb and 1st March and similar increment on Sales needs to be applied
You can use a UDTF to generate the rows for each day of the month along with an extrapolation of the sales.
create or replace table T1 as
select
COLUMN1::date as Date,
COLUMN2::string as Country,
COLUMN3::string as Region,
COLUMN4::number(38,2) as Sales
from (values
('01/01/2022','UK','EMEA',100000),
('02/01/2022','UK','EMEA',170000),
('03/01/2022','UK','EMEA',120000),
('01/01/2022','US','AMS',90000),
('02/01/2022','US','AMS',110000),
('03/01/2022','US','AMS',160000)
);
create or replace function EXTRAPOLATE_MONTH_TO_DAYS(MONTH_START date, VAL float)
returns table (DAY_DATE date, VAL float)
language javascript
as
$$
{
initialize: function (argumentInfo, context) {
},
processRow: function (row, rowWriter, context) {
const DAY = 86400000; // Milliseconds per day.
let firstDay = row.MONTH_START;
let lastDay = new Date(row.MONTH_START.getFullYear(), row.MONTH_START.getMonth() + 1, 0);
let daysInMonth = lastDay.getDate();
let valPerDay = row.VAL / daysInMonth;
let sum = 0;
let curDate = row.MONTH_START;
for (let i = 1; i <= daysInMonth; i++) {
sum += valPerDay;
rowWriter.writeRow({DAY_DATE:new Date(firstDay.getTime()+DAY*(i-1)),VAL:sum});
}
},
}
$$;
select DATE
,COUNTRY
,REGION
,SALES
,DAY_DATE
,round(VAL,2)::number(38,2) EXTRAPOLATED_RUNNING_TOTAL
from T1, table(EXTRAPOLATE_MONTH_TO_DAYS(DATE, SALES::float) over (partition by COUNTRY, REGION order by DATE))
;
First five rows:
DATE | COUNTRY | REGION | SALES | DAY_DATE | EXTRAPOLATED_RUNNING_TOTAL |
---|---|---|---|---|---|
2022-01-01 | US | AMS | 90000 | 2022-01-01 | 2903.23 |
2022-01-01 | US | AMS | 90000 | 2022-01-02 | 5806.45 |
2022-01-01 | US | AMS | 90000 | 2022-01-03 | 8709.68 |
2022-01-01 | US | AMS | 90000 | 2022-01-04 | 11612.90 |
2022-01-01 | US | AMS | 90000 | 2022-01-05 | 14516.13 |
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.