SQL命令分配平均值

时间:2014-09-23 10:30:55

标签: sql sql-server sql-server-2014

我需要了解如何在sql中执行此操作。使用SQL Server Management Studio 我有一个大表,其中包含

等数据
Store           Month              Value
------         --------           -------
  A              JAN               1000
  A              FEB               2400
  A              MAR               2310
  A              APR               1409
  A              MAY               1500
  A              JUN               1000
  A              JUL               2400
  A              AUG               2310
  A              SEP               1409
  A              OCT               1500
  A              NOV               1409
  A              DEC               1500

我有上述数据,但我希望按日期得到月份的平均值。例如

Store           Month              Value
------         --------           -------
  A           1/1/2014             32.25
  A           2/1/2014             32.25
  A           3/1/2014             32.25
  A           4/1/2014             32.25
  .              .                   .
  .              .                   .
  .              .                   .
  .              .                   .
  A           31/1/2014             32.25

其中32.25的值来自于将JAN(31)中的总天数除以1000的值...

1000/31 = 32.25

在接下来的几个月里,我必须这样做。

任何人都知道我该怎么办?我完全被困了。我尝试使用excel手动完成,但有太多的数据和不同的商店

1 个答案:

答案 0 :(得分:1)

因此,您希望查找当月的天数,并使用它来分割每天的值。如果你不想要实际的日期范围,只需要一个月+平均值。每天,然后第一个查询应该工作,完整的日期范围包含在最后一个查询中。

请注意,我使用2014年作为年份,因此如果您想运行闰年的查询,则必须进行相应的调整。

对于SQL Server 2012+ :(使用新的eomonth函数)

select 
    store, month, value, 
    cast(value as decimal(10,2)) / datepart(day,eomonth(cast('2014-' + month + '-01' as date))) as val_per_day
from table1

对于SQL Server< 2012年:(使用日期函数)

select 
    store, month, value,
    cast(value as decimal(10,2))/datepart(day,
    cast(dateadd(month, datediff(month, 0, cast('2014-' + month + '-01' as date))+1, 0)-1 as date)) as val_per_day
from table1

如果您也想要这些日子,您可以使用公用表格表达式来生成包含一年中所有日期的表格,并将其用于左连接:

;With cte(d) as
(
    select cast('2014-01-01' as date) as d
        union all
    select dateadd(day, 1, d)
        from cte
        where d < '2014-12-31'
)

select *,
    cast(Value as decimal(10,2))/ 
    -- for pre 2012
    datepart(day,cast(dateadd(month, datediff(month, 0, cast('2014-' + month + '-01' as date))+1, 0)-1 as date)) as val_per_day
    --day(EOMONTH(d))  -- for 2012
from cte c
left join table1 t on t.month = left(datename(month, d),3)
option (MaxRecursion 1000)

Sample SQL Fiddle显示结果。