我使用以下查询动态计算预算值意味着迭代到所选日期值。
SUM(case when Name = 'Budget' then Value + ((Value/@TotaldaysinMonth) *
@DaysPastinMonth) end) as [Budget]
此变量@DaysPastinMonth
应该是动态的。表示我选择日期为03/31/2017
。然后查询应该运行到上个月的值。另一个例子是如果我选择August,那么我需要从1月到8月运行查询。
For Jan
SUM(case when Name = 'Budget' then Value + ((Value/@TotaldaysinMonth) *
@DaysPastinJanMonth) end) as [Budget]
For Feb
SUM(case when Name = 'Budget' then Value + ((Value/@TotaldaysinMonth) *
@DaysPastinFebMonth) end) as [Budget]
For Mar
SUM(case when Name = 'Budget' then Value + ((Value/@TotaldaysinMonth) *
@DaysPastinMarMonth) end) as [Budget]
此外,我已经为持有DaysPastinMonth的所有12个月创建了变量。
任何人都可以建议如何使用案例陈述来实现这一目标。
答案 0 :(得分:0)
当你可以使用基于集合的操作时,你正在考虑这个循环。
----------------------------------------------------------
--Create a table of dates for testing
----------------------------------------------------------
if object_id('tempdb..#dates') is not null
drop table #dates
create table #dates(d date
,RN bigint)
declare @sdate datetime='2017-01-01 00:00'
declare @edate datetime='2017-7-31 00:00'
insert into #dates
select
DATEADD(d,number,@sdate)
,row_number() over (order by (select null)) as RN
from
master..spt_values
where
type='P'
and number<=datediff(d,@sdate,@edate)
declare @numOfDays int = (select count(*) from #dates)
----------------------------------------------------------
--Populate Test Data
----------------------------------------------------------
if object_id('tempdb..#testTable') is not null
drop table #testTable
create table #testTable([Name] varchar(64),
[Value] decimal (16,4),
DT datetime)
insert into #testTable ([Name],[Value],DT)
select
'Budget'
,r.randomNumber
,d.d
from
#dates d
inner join
(SELECT TOP (select @numOfDays)
randomNumber,
row_number() over (order by (select null)) as RN
FROM (
SELECT CAST(ABS(CAST(NEWID() AS binary(6)) %100000) + RAND() AS DECIMAL (16,4)) + 1 randomNumber
FROM sysobjects) sample
GROUP BY randomNumber
ORDER BY randomNumber DESC) r on r.RN = d.RN
union all
select
'Not The Budget'
,r.randomNumber
,d.d
from
#dates d
inner join
(SELECT TOP (select @numOfDays)
randomNumber,
row_number() over (order by (select null)) as RN
FROM (
SELECT CAST(ABS(CAST(NEWID() AS binary(6)) %100000) + RAND() AS DECIMAL (16,4)) + 1 randomNumber
FROM sysobjects) sample
GROUP BY randomNumber
ORDER BY randomNumber DESC) r on r.RN = d.RN
----------------------------------------------------------
--Instead of making your variables "dynamic" which
--would likely consist of some loop, just pass in the
--month you care about and let SQL do the work
----------------------------------------------------------
declare @month datetime = '2016-03-31'
select
DT
,[Value]
,[Name]
,sum(case when [Name] = 'Budget'
then [Value] +
(([Value] / (DATEDIFF(day,DATEADD(month, DATEDIFF(month, 0, @month), 0),@month)))
*
(DATEDIFF(DAY,DATEADD(MONTH, DATEDIFF(MONTH, 0, @month)-1, 0),DATEADD(MONTH, DATEDIFF(MONTH, -1, @month)-1, -1)))) end) as Budget
from
#testTable
where
DT >= DATEADD(yy, DATEDIFF(yy, 0, @month), 0) --this is Jan 1 of the year associated with your vairable
group by
DT
,[Name]
,[Value]