Skip to content
Advertisement

disaggregate 3d time periods into daily

table_1 shows the aggregation of the revenue by different geographies

date           revenue_North_AM  revenue_Asia  revenue_Africa revenue_Oceania
2020-01-01          172               38              10           20
2020-01-04          125              100              30           55 
2020-01-07          202              312              20           85
2020-01-10          212               35               0           35               
2020-01-13          120               50              30           20

I would like to disaggregate the 3d period to daily: table_2

date           revenue_North_AM  revenue_Asia  revenue_Africa revenue_Oceania
2020-01-01          57.33             12.66          3.33          6.66
2020-01-02          57.33             12.66          3.33          6.66
2020-01-03          57.33             12.66          3.33          6.66
2020-01-04          41.66             33.33         10.00         18.33 
2020-01-05          41.66             33.33         10.00         18.33
2020-01-06          41.66             33.33         10.00         18.33
....

as a next step, I would like to also change the table_2 format into table_3:

date           region       revenue
2020-01-01     North_AM      57.33
2020-01-01     Asia          12.66
2020-01-01     Africa         3.33
2020-01-01     Oceania        6.66

From table_1 to table_2, I am not sure. From table_2 to table_3, I am thinking of:

select t2.region, t2.revenue 
from schema.table_2 t2
  cross join lateral (
    values
      (t2.revenue_North_AM, 'North_AM'),
      (t2.revenue_Asia, 'Asia'),
      (t2.revenue_Africa, 'Africa')
      (t2.revenue_Oceania, 'Oceania')
      ) as t3(revenue, region)

With the code above, however, the date column is not included into the cross join..

Advertisement

Answer

To go from table 1 to table 3 using the logic that you propose:

select t1.date, t3.region, t3.revenue 
from (select gs.date,
             revenue_North_AM / num_days as revenue_North_AM,
             revenue_Asia / num_days as revenue_Asia,
             revenue_Africa / num_days as revenue_Africa,
             revenue_Oceania / num_days as revenue_Oceania
      from (select t1.*,
                   coalesce(lead(date) over (order by date) - interval '1 day', date) as last_date,
                   (lead(date) over (order by date) - date) as num_days
            from table_1 t1
           ) t1 cross join
           generate_series(date, last_date, interval '1 day') gs(date)
     ) t1 cross join lateral
     (values (t1.revenue_North_AM, 'North_AM'),
             (t1.revenue_Asia, 'Asia'),
             (t1.revenue_Africa, 'Africa'),
             (t1.revenue_Oceania, 'Oceania')
     ) t3(revenue, region);

Here is a db<>fiddle.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement