Sql 动态迭代值
我使用下面的查询来动态计算预算值,这意味着迭代到选定的日期值Sql 动态迭代值,sql,sql-server,sql-server-2012,sql-server-2014,Sql,Sql Server,Sql Server 2012,Sql Server 2014,我使用下面的查询来动态计算预算值,这意味着迭代到选定的日期值 SUM(case when Name = 'Budget' then Value + ((Value/@TotaldaysinMonth) * @DaysPastinMonth) end) as [Budget] 这里的变量@DaysPastinMonth应该是动态的。表示如果我选择日期为2017年3月31日。然后,查询应该运行到上个月的值。另一个例子是,如果我选择八月,那么我需要从一月到八月运行查询 一月 二月 三月 我还为所
SUM(case when Name = 'Budget' then Value + ((Value/@TotaldaysinMonth) *
@DaysPastinMonth) end) as [Budget]
这里的变量@DaysPastinMonth应该是动态的。表示如果我选择日期为2017年3月31日。然后,查询应该运行到上个月的值。另一个例子是,如果我选择八月,那么我需要从一月到八月运行查询
一月
二月
三月
我还为所有12个月创建了变量,这12个月包含DaysPastinMonth
任何人都可以建议如何使用case语句来实现这一点。当您可以使用基于集合的操作时,您正在循环中考虑这一点
----------------------------------------------------------
--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]
不清楚你在问什么。显示输入和输出数据。因此,如果日期是2017年1月4日,@DaysPastinMonth的值是多少?我认为您应该发布示例数据并显示预期输出。所以每个人都可以很容易地帮上忙。
SUM(case when Name = 'Budget' then Value + ((Value/@TotaldaysinMonth) *
@DaysPastinFebMonth) end) as [Budget]
SUM(case when Name = 'Budget' then Value + ((Value/@TotaldaysinMonth) *
@DaysPastinMarMonth) end) as [Budget]
----------------------------------------------------------
--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]