SQL根据条件求和特定行?

时间:2019-03-04 12:32:37

标签: sql sql-server

我正在使用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

但是从上面我无法达到结果。 我该如何解决?谢谢。

3 个答案:

答案 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