Reputation: 97
Hello again good stack people. I am faced with the dilemma of getting the weekly average per day (for example, Monday_Avg, Tuesday_Avg…etc) for the previous month I have succeeded in getting the monthly average for the previous month with the following code. However, I do not have enough know how of date/time functions in sql to complete this task.
This works for me for getting monthly average.
ALTER procedure [dbo].[usp_consumation]
@strMonth varchar(2),
@strYear varchar(4),
@strPrevMonth varchar(2),
@strPrevYear varchar(4)
as
--set @strMonth = '05'
--set @strYear = '2013'
--set @strPrevMonth = '04'
--set @strPrevYear = '2013'
declare @tbl_PrevMonthAverage table(cell varchar(25),average_d numeric(18,4))
drop table ##tempCIUnits
drop table ##tempCIUnitsTotal
declare @FieldName varchar(150)
declare @FieldAbv varchar(50)
declare @strSql varchar(8000)
declare @strFields varchar(5000)
declare @strFieldsSum varchar(5000)
declare @intCounter integer
\
--Get avarage past month
set @strFields = ' '
set @intCounter = 0
declare curStrSQLUnits cursor for
select name, right(name,4) name_abv
from sys.columns
where system_type_id = 108
and object_id = isnull((select top 1 id from sites.dbo.sysobjects where name = 'tbl_Revenue_'+@strPrevYear+@strPrevMonth),0)
and name like 'count_d_%'
order by name asc
open curStrSQLUnits
fetch next from curStrSQLUnits into @FieldName,@FieldAbv
while @@fetch_status = 0
begin
set @intCounter = @intCounter + 1
set @strFields = @strFields + @FieldName + '+'
fetch next from curStrSQLUnits into @FieldName,@FieldAbv
end
close curStrSQLUnits
deallocate curStrSQLUnits
set @strFields = left(@strFields,len(@strFields)-1)
set @strSql = 'select [Cell], (' + @strFields + ')/'+CONVERT(varchar,@intCounter)+' as avg_previous_month '
set @strSql = @strSql + ' from sites.dbo.tbl_Revenue_'+@strPrevYear+@strPrevMonth + ' order by Cell asc'
insert into @tbl_PrevMonthAverage(cell,average_d) exec (@strSql)
Another method of solving the problem.
USE [Sites]
GO
declare @strPrevMonth varchar(2)
declare @strPrevYear varchar(4)
set @strPrevMonth = '07'
set @strPrevYear = '2013'
declare @FieldName varchar(150)
declare @FieldAbv varchar(50)
declare @strSql varchar(8000)
declare @strFieldsSum varchar(5000)
declare @intCounter integer
declare @strFields varchar(5000)
declare @intCounter_1 integer
declare @strFields_1 varchar(5000)
declare @intCounter_2 integer
declare @strFields_2 varchar(5000)
declare @intCounter_3 integer
declare @strFields_3 varchar(5000)
declare @intCounter_4 integer
declare @strFields_4 varchar(5000)
declare @intCounter_5 integer
declare @strFields_5 varchar(5000)
declare @intCounter_6 integer
declare @strFields_6 varchar(5000)
declare @intCounter_7 integer
declare @strFields_7 varchar(5000)
--Get avarage past month
set @strFields = ' '
set @intCounter = 0
set @strFields_1 = ' '
set @intCounter_1 = 0
set @strFields_2 = ' '
set @intCounter_2 = 0
set @strFields_3 = ' '
set @intCounter_3 = 0
set @strFields_4 = ' '
set @intCounter_4 = 0
set @strFields_5 = ' '
set @intCounter_5 = 0
set @strFields_6 = ' '
set @intCounter_6 = 0
set @strFields_7 = ' '
set @intCounter_7 = 0
declare curStrSQLUnits cursor for
select name, right(name,4) name_abv
from sys.columns
where system_type_id = 108
and object_id = isnull((select top 1 id from sites.dbo.sysobjects where name = 'tbl_CellId_Revenue_'+@strPrevYear+@strPrevMonth),0)
and name like 'minutes_d_%'
order by name asc
open curStrSQLUnits
fetch next from curStrSQLUnits into @FieldName,@FieldAbv
while @@FETCH_STATUS = 0
begin
set @intCounter = @intCounter + 1
set @strFields = @strFields + @FieldName + '+'
if (datepart(weekday,@strPrevMonth+'/'+RIGHT(@FieldName,2)+'/'+@strPrevYear)) = 1
begin
set @intCounter_1 = @intCounter_1 + 1
set @strFields_1 = @strFields_1 + @FieldName + '+'
end
if (datepart(weekday,@strPrevMonth+'/'+RIGHT(@FieldName,2)+'/'+@strPrevYear)) = 2
begin
set @intCounter_2 = @intCounter_2 + 1
set @strFields_2 = @strFields_2 + @FieldName + '+'
end
if (datepart(weekday,@strPrevMonth+'/'+RIGHT(@FieldName,2)+'/'+@strPrevYear)) = 3
begin
set @intCounter_3 = @intCounter_3 + 1
set @strFields_3 = @strFields_3 + @FieldName + '+'
end
if (datepart(weekday,@strPrevMonth+'/'+RIGHT(@FieldName,2)+'/'+@strPrevYear)) = 4
begin
set @intCounter_4 = @intCounter_4 + 1
set @strFields_4 = @strFields_4 + @FieldName + '+'
end
if (datepart(weekday,@strPrevMonth+'/'+RIGHT(@FieldName,2)+'/'+@strPrevYear)) = 5
begin
set @intCounter_5 = @intCounter_5 + 1
set @strFields_5 = @strFields_5 + @FieldName + '+'
end
if (datepart(weekday,@strPrevMonth+'/'+RIGHT(@FieldName,2)+'/'+@strPrevYear)) = 6
begin
set @intCounter_6 = @intCounter_6 + 1
set @strFields_6 = @strFields_6 + @FieldName + '+'
end
if (datepart(weekday,@strPrevMonth+'/'+RIGHT(@FieldName,2)+'/'+@strPrevYear)) = 7
begin
set @intCounter_7 = @intCounter_7 + 1
set @strFields_7 = @strFields_7 + @FieldName + '+'
end
fetch next from curStrSQLUnits into @FieldName,@FieldAbv
end
close curStrSQLUnits
deallocate curStrSQLUnits
set @strFields = left(@strFields,len(@strFields)-1)
set @strFields_1 = left(@strFields_1,len(@strFields_1)-1)
set @strFields_2 = left(@strFields_2,len(@strFields_2)-1)
set @strFields_3 = left(@strFields_3,len(@strFields_3)-1)
set @strFields_4 = left(@strFields_4,len(@strFields_4)-1)
set @strFields_5 = left(@strFields_5,len(@strFields_5)-1)
set @strFields_6 = left(@strFields_6,len(@strFields_6)-1)
set @strFields_7 = left(@strFields_7,len(@strFields_7)-1)
set @strSql = 'select isnull((' + @strFields_1 + '),0)/'+CONVERT(varchar,@intCounter_1)+' as Sun_Avg_PrevMnth '
set @strSql = @strSql + ', isnull((' + @strFields_2 + '),0)/'+CONVERT(varchar,@intCounter_2)+' as Mon_Avg_PrevMnth '
set @strSql = @strSql + ', isnull((' + @strFields_3 + '),0)/'+CONVERT(varchar,@intCounter_3)+' as Tue_Avg_PrevMnth '
set @strSql = @strSql + ', isnull((' + @strFields_4 + '),0)/'+CONVERT(varchar,@intCounter_4)+' as Wed_Avg_PrevMnth '
set @strSql = @strSql + ', isnull((' + @strFields_5 + '),0)/'+CONVERT(varchar,@intCounter_5)+' as Thu_Avg_PrevMnth '
set @strSql = @strSql + ', isnull((' + @strFields_6 + '),0)/'+CONVERT(varchar,@intCounter_6)+' as Fri_Avg_PrevMnth '
set @strSql = @strSql + ', isnull((' + @strFields_7 + '),0)/'+CONVERT(varchar,@intCounter_7)+' as Sat_Avg_PrevMnth '
set @strSql = @strSql + ' from sites.dbo.tbl_Revenue_'+@strPrevYear+@strPrevMonth + ' order by CellId asc'
exec (@strSql)
Upvotes: 0
Views: 173
Reputation: 280423
I'm going to answer what I think you mean by "Weekly Average (per day)" with a very simple example, and then let you work out how you need to incorporate it into this massive stored procedure with all sorts of code that seems irrelevant to the actual problem you're trying to solve. I could go on and on about how you're incorrectly using global temp tables or questioning why you need a table variable or doubting the sanity of tables named tbl_Revenue_201307
, but again, they don't seem like they have anything to do with the problem you have:
getting the weekly average per day (for example, Monday_Avg, Tuesday_Avg…etc) for the previous month ...
I do not have enough know how of date/time functions in sql to complete this task.
Let's say you have a table with four columns, one datetime
and three decimal(18,2)
:
CREATE TABLE dbo.tbl_Revenue_201307
(
d DATETIME,
val1 DECIMAL(18,2),
val2 DECIMAL(18,2),
val3 DECIMAL(18,2)
);
Some sample data:
INSERT dbo.tbl_Revenue_201307 VALUES
('20130701',12,15,18),('20130701',13,14,15),('20130702',5,1,5),
('20130703',12,15,18),('20130703',13,9,13),('20130703',5,1,5),
('20130704',12,15,18),('20130704',13,1,12),('20130705',5,1,5),
('20130705',12,15,18),('20130706',13,11,16),('20130714',5,1,5);
You want to look at all of the data for that month, and average "it" ("it" meaning the sum of val1
+val2
+val3
) per weekday. So, one value that represents the average over all Sundays in the month, one value that represents the average over all Mondays, etc. for a total of 7 individual values. Two queries that can do that (depending on whether you want the data in rows or columns):
SELECT
wd = DATEPART(WEEKDAY, date_col),
dn = LEFT(DATENAME(WEEKDAY, date_col), 3) + '_Avg',
[avg] = AVG(val1 + val2 + val3)
FROM dbo.tbl_Revenue_201307
GROUP BY DATENAME(WEEKDAY, date_col), DATEPART(WEEKDAY, date_col)
ORDER BY wd;
SELECT * FROM
(
SELECT
col = LEFT(DATENAME(WEEKDAY, date_col),3) + '_Avg',
val = AVG(val1 + val2 + val3)
FROM dbo.tbl_Revenue_201307
GROUP BY LEFT(DATENAME(WEEKDAY, date_col),3)
) AS p
PIVOT (MAX(val) FOR col IN
([Sun_Avg],[Mon_Avg],[Tue_Avg],[Wed_Avg],[Thu_Avg],[Fri_Avg],[Sat_Avg])) AS d;
Results:
wd dn avg
-- ------- ---------
1 Sun_Avg 11.000000
2 Mon_Avg 43.500000
3 Tue_Avg 11.000000
4 Wed_Avg 30.333333
5 Thu_Avg 35.500000
6 Fri_Avg 28.000000
7 Sat_Avg 40.000000
Sun_Avg Mon_Avg Tue_Avg Wed_Avg Thu_Avg Fri_Avg Sat_Avg
--------- --------- --------- --------- --------- --------- ---------
11.000000 43.500000 11.000000 30.333333 35.500000 28.000000 40.000000
Upvotes: 1