我有一张如下表格
Item Name | Date | Previous Data | Updated Data
Unit 1 | 1-Jul-2013 | 500 | 550
Unit 1 | 1-Aug-2013 | 550 | 550
Unit 1 | 1-Sep-2013 | 450 | 600
Unit 1 | 1-Oct-2013 | 600 | 550
使用pivot功能,我将它们显示如下:
Title | Jul | Aug | Sep | Oct
Prev. Data| 500 | 550 | 450 | 600
Upd. Data | 550 | 550 | 600 | 550
现在,这是我想要实现的棘手部分。上一篇数据预先作为预测方式键入。当实际月份到来时,我们才会键入Upd。数据。
我想在上个月(即12月)旁边添加另一个名为YTD的列(年初至今),该列计算每个类别的加权平均值。假设我们现在在十月,加权平均计算方法将是
YTD = (Jan*(#Days in Jan) + Feb*(#Days in Feb) + ... + Oct*(#Days in Oct))/(Total days in a year)
目前,我的查询如下所示;
Select col,
[1] as Jan,
[2] Feb,
[3] Mar,
[4] Apr,
[5] May,
[6] Jun,
[7] Jul,
[8] Aug,
[9] Sep,
[10] Oct,
[11] Nov,
[12] Dec,
(isnull([1],0)+isnull([2],0)+isnull([3],0))/3 as Q1,
(isnull([4],0)+isnull([5],0)+isnull([6],0))/3 as Q2,
(isnull([7],0)+isnull([8],0)+isnull([9],0))/3 as Q3,
(isnull([10],0)+isnull([11],0)+isnull([12],0))/3 as Q4
from
(
select month(Date) as TMonth, col, value
from Table1
cross apply
(
select 'Previous Data', [Previous Data]
union all
select 'Updated Date', [Updated Data]
) c(col, value)
)a
PIVOT
(
AVG(value)
for Tmonth in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])
)pvt
请有人帮助我如何实现这一目标吗?
我正在使用SQL Server 2008 R2
答案 0 :(得分:0)
这有点棘手,但这里是包含YTD_WtdAvg列的更新查询。我在结果中添加了年份,因为为了根据一个月和一年中的天数进行wtd avg,您必须知道自2月以来的数据年份是否有不同的天数取决于年份
根据YTD = (Jan*(#Days in Jan) + Feb*(#Days in Feb) + ... + Oct*(#Days in Oct))/(Total days in a year)
的OP公式,查询仍然会除以一年中的总天数,即使今天不是十二月。
Select
pvt.TYear,
pvt.FirstDayOfYear,
pvt.DaysInYear,
pvt.col,
[1] as Jan,
[2] Feb,
[3] Mar,
[4] Apr,
[5] May,
[6] Jun,
[7] Jul,
[8] Aug,
[9] Sep,
[10] Oct,
[11] Nov,
[12] Dec,
(isnull([1],0)+isnull([2],0)+isnull([3],0))/3 as Q1,
(isnull([4],0)+isnull([5],0)+isnull([6],0))/3 as Q2,
(isnull([7],0)+isnull([8],0)+isnull([9],0))/3 as Q3,
(isnull([10],0)+isnull([11],0)+isnull([12],0))/3 as Q4,
(
case when pvt.TYear < year(getdate()) OR pvt.TYear = year(getdate()) AND month(getdate()) <= 1 then isnull(pvt.[1] * datediff(day, dateadd(month, 0, pvt.FirstDayOfYear), dateadd(month, 1, pvt.FirstDayOfYear)), 0) else 0 end
+ case when pvt.TYear < year(getdate()) OR pvt.TYear = year(getdate()) AND month(getdate()) <= 2 then isnull(pvt.[2] * datediff(day, dateadd(month, 1, pvt.FirstDayOfYear), dateadd(month, 2, pvt.FirstDayOfYear)), 0) else 0 end
+ case when pvt.TYear < year(getdate()) OR pvt.TYear = year(getdate()) AND month(getdate()) <= 3 then isnull(pvt.[3] * datediff(day, dateadd(month, 2, pvt.FirstDayOfYear), dateadd(month, 3, pvt.FirstDayOfYear)), 0) else 0 end
+ case when pvt.TYear < year(getdate()) OR pvt.TYear = year(getdate()) AND month(getdate()) <= 4 then isnull(pvt.[4] * datediff(day, dateadd(month, 3, pvt.FirstDayOfYear), dateadd(month, 4, pvt.FirstDayOfYear)), 0) else 0 end
+ case when pvt.TYear < year(getdate()) OR pvt.TYear = year(getdate()) AND month(getdate()) <= 5 then isnull(pvt.[5] * datediff(day, dateadd(month, 4, pvt.FirstDayOfYear), dateadd(month, 5, pvt.FirstDayOfYear)), 0) else 0 end
+ case when pvt.TYear < year(getdate()) OR pvt.TYear = year(getdate()) AND month(getdate()) <= 6 then isnull(pvt.[6] * datediff(day, dateadd(month, 5, pvt.FirstDayOfYear), dateadd(month, 6, pvt.FirstDayOfYear)), 0) else 0 end
+ case when pvt.TYear < year(getdate()) OR pvt.TYear = year(getdate()) AND month(getdate()) <= 7 then isnull(pvt.[7] * datediff(day, dateadd(month, 6, pvt.FirstDayOfYear), dateadd(month, 7, pvt.FirstDayOfYear)), 0) else 0 end
+ case when pvt.TYear < year(getdate()) OR pvt.TYear = year(getdate()) AND month(getdate()) <= 8 then isnull(pvt.[8] * datediff(day, dateadd(month, 7, pvt.FirstDayOfYear), dateadd(month, 8, pvt.FirstDayOfYear)), 0) else 0 end
+ case when pvt.TYear < year(getdate()) OR pvt.TYear = year(getdate()) AND month(getdate()) <= 9 then isnull(pvt.[9] * datediff(day, dateadd(month, 8, pvt.FirstDayOfYear), dateadd(month, 9, pvt.FirstDayOfYear)), 0) else 0 end
+ case when pvt.TYear < year(getdate()) OR pvt.TYear = year(getdate()) AND month(getdate()) <= 10 then isnull(pvt.[10] * datediff(day, dateadd(month, 9, pvt.FirstDayOfYear), dateadd(month, 10, pvt.FirstDayOfYear)), 0) else 0 end
+ case when pvt.TYear < year(getdate()) OR pvt.TYear = year(getdate()) AND month(getdate()) <= 11 then isnull(pvt.[11] * datediff(day, dateadd(month, 10, pvt.FirstDayOfYear), dateadd(month, 11, pvt.FirstDayOfYear)), 0) else 0 end
+ case when pvt.TYear < year(getdate()) OR pvt.TYear = year(getdate()) AND month(getdate()) <= 12 then isnull(pvt.[12] * datediff(day, dateadd(month, 11, pvt.FirstDayOfYear), dateadd(month, 12, pvt.FirstDayOfYear)), 0) else 0 end
)
/ pvt.DaysInYear
as YTD_WtdAvg
from
(
select year(Date) as TYear
, d.FirstDayOfYear
, datediff(day, d.FirstDayOfYear, dateadd(year, 1, d.FirstDayOfYear)) as DaysInYear
, month(date) as TMonth
, col, value
from Table1 t
cross apply
(
select 'Previous Data', [Previous Data]
union all
select 'Updated Data', [Updated Data]
) c(col, value)
cross apply
(
select dateadd(year, datediff(year, 0, t.date), 0) as FirstDayOfYear
) d
)a
PIVOT
(
AVG(value)
for Tmonth in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])
)pvt