Reputation: 1040
I am using MS SQL Server
. This is the table I have:
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')
Table as this:
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
This is what I want:
Mon | Total
------------------
Jan | 500
Feb | 841
March | 841
April | 1561
May | 1561
June | 1561
July | 2100
........|.........
I want to sum Val
column if it lies in that particular month. For ex. in case of April
month it lies between two of the rows. I have to check both the condition start date and end date. and then sum the values.
This is what I have tried:
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
but from above I was unable to achieve the result. How do I solve this? Thanks.
Upvotes: 4
Views: 2848
Reputation: 1012
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
Upvotes: 1
Reputation: 1180
Hi if i understand your wall query i think this query can respond :
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
Not you have to use SQL Server version 2008 min for use OVER(ORDER BY iMonth ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
Link :
If you have older version you can use CTE or JOIN ON select .
Upvotes: 1
Reputation: 1269493
I believe you want something like this:
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;
This does the calculation for all months in the data.
The results are a bit different from your sample results, but seem more consistent with the data provided.
Here is a db<>fiddle.
Upvotes: 3