I am new to SQL. I am trying to create an over view using these 2 tables
Actual sale
Week_Year
Unit 34_2020 35_2020 36_2020 37_2020 Unit 1 10 12 15 19 Unit 2 10 12 15 19 Unit 3 10 12 15 19
Target sale
Unit Total to be sold Start Date End Date Unit 1 50 24-08-20 24-09-20 Unit 2 1000 18-01-20 01-01-21 Unit 3 1000 05-02-20 01-10-20
To combine into this resulting view with Targets and Actuals:
Unit 1 Unit 2 Unit 3 Week Target Actual Week Target Actual Week Target Actual 34_2020 11 10 3_2020 20 10 6_2020 20 10 35_2020 24 12 4_2020 40 12 7_2020 40 12 36_2020 36 15 5_2020 60 15 8_2020 60 15 37_2020 50 19 6_2020 80 19 9_2020 80 19 . 100 . . 100 . 36_2020 120 95 36_2020 700 650 37_2020 140 100 37_2020 800 700 . . 38_2020 . . . 39_2020 . . . 40_2020 1000 1_2021 1000
where column Target is ‘Total to be sold’ spread linearly between the available weeks.
How can I achieve this using SQL Server? Any inputs much appreciated. Thanks.
Advertisement
Answer
In order to make the week numbers (34, 35, 36, 37) correspond to system weeks the variable @start_wk_no sets the starting point. The actual sales needs to be unpivoted to join with projected sales. The query uses a tally (or numbers) function to generate the rows.
Data
drop table if exists dbo.test_actuals; go create table dbo.test_actuals( Unit varchar(100) not null, [34_2020] int not null, [35_2020] int not null, [36_2020] int not null, [37_2020] int not null); --select * from dbo.test_actuals insert dbo.test_actuals values ('Unit 1', 10, 12, 15, 19), ('Unit 2', 10, 12, 15, 19), ('Unit 3', 10, 12, 15, 19); drop table if exists dbo.test_target; go create table dbo.test_target( Unit varchar(100) not null, TotalToSell int not null, StartDate date not null, EndDate date not null) insert dbo.test_target values ('Unit 1', 50, '08-24-2020', '09-24-2020'), ('Unit 2', 1000, '01-18-2020', '01-01-2021'), ('Unit 3', 1000, '02-05-2020', '10-01-20');
Query
/* based on system weeks, what is the start point */ declare @start_wk_no int=6250; ;with unpvt_actuals_cte as ( select a.Unit, v.* from dbo.test_actuals a cross apply (values (34, [34_2020]), (35, [35_2020]), (36, [36_2020]), (36, [36_2020]), (37, [37_2020])) v([Week], act_sales)) select t.Unit, wd.wk_proj [Week], isnull(act.act_sales, 0) [Actual], TotalToSell/(wk_diff.wk_diff*1.0) [Target], sum(TotalToSell/(wk_diff.wk_diff*1.0)) over (partition by t.Unit order by wd.wk_proj) Cum_Target from dbo.test_target t cross apply (select datediff(wk, t.StartDate, t.EndDate) wk_diff) wk_diff cross apply dbo.fnTally(0, wk_diff.wk_diff-1) f cross apply (select dateadd(wk, f.n, t.StartDate) wk_dt) wk cross apply (select datediff(week, 0, wk.wk_dt)-@start_wk_no wk_proj) wd left join unpvt_actuals_cte act on t.Unit=act.Unit and wd.wk_proj=act.[Week];