我正在使用MS SQL Server
。这是我的桌子:
Create table tblVal
(
Id int identity(1,1),
Val NVARCHAR(100),
startdate datetime,
enddate datetime
)
--Inserting Records--
Insert into tblVal values(500,'20180907','20191212')
Insert into tblVal values(720,'20190407','20191212')
Insert into tblVal values(539,'20190708','20201212')
Insert into tblVal values(341,'20190221','20190712')
表格如下:
Id |Val |startdate |enddate
--- ----------------------------------------------
1 |500 |2018-09-07 |2019-12-12
2 |720 |2019-04-07 |2019-12-12
3 |539 |2019-07-08 |2020-12-12
4 |341 |2019-02-21 |2019-07-12
这就是我想要的:
Mon | Total
------------------
Jan | 500
Feb | 841
March | 841
April | 1561
May | 1561
June | 1561
July | 2100
........|.........
如果Val
列位于该特定月份,我想对其加总。对于前。如果是April
月,则它位于两行之间。我必须检查条件开始日期和结束日期。然后将值求和。
这是我尝试过的:
select *
into #ControlTable
from dbo.tblVal
DECLARE @cnt INT = 0;
while @cnt<12
begin
select sum(CASE
WHEN MONTH(startdate) BETWEEN @cnt and MONTH(enddate) THEN 0
ELSE 0
END)
from #ControlTable
SET @cnt = @cnt + 1;
end
drop table #ControlTable
但是从上面我无法达到结果。 我该如何解决?谢谢。
答案 0 :(得分:3)
我相信您想要这样的东西:
with dates as (
select min(datefromparts(year(startdate), month(startdate), 1)) as dte,
max(datefromparts(year(enddate), month(enddate), 1)) as enddte
from tblVal
union all
select dateadd(month, 1, dte), enddte
from dates
where dte < enddte
)
select d.dte, sum(val)
from dates d left join
tblval t
on t.startdate <= eomonth(dte) and
t.enddate >= dte
group by d.dte
order by d.dte;
这将对数据中的所有月份进行计算。
结果与样本结果有些不同,但似乎与提供的数据更加一致。
Here是db <>小提琴。
答案 1 :(得分:1)
嗨,如果我了解您的留言墙查询,我认为该查询可以响应:
Create table #tblVal
(
Id int identity(1,1),
Val NVARCHAR(100),
startdate datetime,
enddate datetime
)
--Inserting Records--
Insert into #tblVal values(500,'20180907','20191212')
Insert into #tblVal values(720,'20190407','20191212')
Insert into #tblVal values(539,'20190708','20201212')
Insert into #tblVal values(341,'20190221','20190712')
Create table #tblMonth ( iMonth int)
Insert into #tblMonth values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12);
select * from #tblVal
select * from #tblMonth
SELECT *, SUM(case when Val is null then 0 else cast (Val as int) end) OVER(ORDER BY iMonth
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as 'Totaltime'
FROM #tblMonth
LEFT JOIN #tblVal ON MONTH(startdate) = iMonth
ORDER BY iMonth
drop table #tblVal
drop table #tblMonth
不是必须使用SQL Server 2008 min版本才能使用OVER(ORDER BY iMonth 无边界的行和当前行之间的行)
链接:
如果您使用的是旧版本,则可以使用CTE或JOIN ON select。
答案 2 :(得分:1)
DECLARE @outpuTable Table(
MOn INT,
Total nvarchar(MAX)
)
DECLARE @cnt INT = 1;
while (@cnt<=12)
begin
INSERT INTo @outpuTable VALUES(@cnt,
(select ISNULL(sum(CONVERT(INT,Val)),0)
from tblVal
WHERE @cnt BETWEEN MONTH(startdate) and MONTH(enddate) ))
SET @cnt = @cnt + 1;
end
Select * from @outpuTable