0

こんにちは、良いスタックの人々です。次のコードを使用して、前月の月平均を取得することに成功しました。ただし、このタスクを完了するには、SQL の日付/時刻関数について十分な知識がありません。

これは、毎月の平均を取得するために機能します。

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)

問題を解決する別の方法。

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)
4

1 に答える 1

1

非常に単純な例を使用して、「週平均 (1 日あたり)」の意味に答えてから、この大規模なストアド プロシージャにそれをどのように組み込む必要があるかを説明します。解決しようとしている実際の問題とは無関係です。グローバル一時テーブルを誤って使用している方法、またはテーブル変数が必要な理由を疑問視している方法、または という名前のテーブルの正気性を疑っている方法について何度も続けることができますtbl_Revenue_201307が、繰り返しになりますが、それらは問題とは何の関係もないようです持ってる:

前月の 1 日あたりの週平均 (Monday_Avg、Tuesday_Avg など) を取得しています ...
SQL の日付/時刻関数について十分な知識がなく、このタスクを完了できません。

datetimeoneと threeの 4 つの列を持つテーブルがあるとしますdecimal(18,2)

CREATE TABLE dbo.tbl_Revenue_201307
(
  d DATETIME,
  val1 DECIMAL(18,2),
  val2 DECIMAL(18,2),
  val3 DECIMAL(18,2)
);

いくつかのサンプルデータ:

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);

その月のすべてのデータを調べて、 平日ごとval1の「それ」(「それ」は++の合計を意味する)を平均しval2ます。したがって、その月のすべての日曜日の平均を表す 1 つの値、すべての月曜日の平均を表す 1 つの値など、合計 7 つの個別の値になります。それを行うことができる 2 つのクエリ (行または列のどちらでデータが必要かによって異なります):val3

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;

結果:

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
于 2013-08-22T17:59:33.127 に答える