如何累积值sql

时间:2014-05-27 20:22:34

标签: tsql sql-server-2012

我必须解决问题,不知道该怎么做。我正在使用SQL Server 2012。

我有像这个架构的数据:

 -----------------------------------------------------------------------------------
   DriverId  | BeginDate | EndDate | NextBegin | Rest in | Drive Time | Drive
             |           |         | Date      | Hours   | in Minutes | KM            
 -----------------------------------------------------------------------------------
    integer     datetime   datetime   datetime    integer    integer     decimal(10,3)

 Rest in hours = EndDate - NextBeginDate
 Drive Time in Minutes = BeginDate - EndDate

我必须搜索第一个休息=>然后36个小时

 Do
   Compute how many days are 
   SUM(DriveTime) 
   SUM(TotalKM)
 until next rest => 36 hours
 IF No More Rest EXIT DO
 Loop

从开始到第一次休息是丢弃 从最后的休息到结束是丢弃

我有excel表中的数据,您可以从这里下载:Download Excel with data example

对不起我的英语,我希望你能理解并帮助我,提前谢谢你。

1 个答案:

答案 0 :(得分:1)

查询有几个部分。第一部分拉出Rest> = 36的行并分配行号。结果存储在名为BigRest的CTE中。

with BigRest(RowNumber, DriverId, BeginDate, EndDate)
as
(
select ROW_NUMBER() over(partition by d.DriverId order by d.DriverId, d.BeginDate) RowNumber,d.DriverId, d.BeginDate, d.EndDate
from Drive d 
where d.Rest >= 36
)

然后我根据BeginDate将BigRest中的行号分配给Drive中的每一行(这就是我调用其中包含所有数据的表)。因此,在Rest> = 36的日子里,数据会被有效地分段。每个细分都会得到一个名为DriveGroup的数字。

;with Grouped(DriverId, BeginDate, EndDate, DriveTime, DriveKM, DriveGroup)
as
(
select d.DriverId, d.BeginDate, d.EndDate, d.Drivetime, d.DriveKM, (select Top 1 RowNumber from BigRest b where b.DriverId = d.DriverId and b.BeginDate >= d.BeginDate order by b.BeginDate)
from Drive d 
)

最后,我从Grouped中选择数据,将其与自身的一些聚合数据交叉应用。我们可以过滤掉DriveGroup为1或null的行,因为它们代表了不重要的开始和结束行("什么都不做"行)。

select distinct DriverId, MinBeginDate BeginDate, MaxEndDate EndDate, DATEDIFF(D, MinBeginDate, MaxEndDate)+1 Days, DriveTimeSum Drive, DriveKMSum KM
from
(
select g.DriverId, g.BeginDate, g.EndDate, g.DriveGroup, g.DriveTime, c.DriveTimeSum, c.DriveKMSum, c.MinBeginDate, c.MaxEndDate
from Grouped g
cross apply(select SUM(g2.DriveTime) DriveTimeSum, 
               SUM(g2.DriveKM) DriveKMSum, 
               MIN(g2.BeginDate) MinBeginDate, 
               MAX(g2.EndDate) MaxEndDate 
               from Grouped g2 
               where g2.DriverId = g.DriverId 
               and g2.DriveGroup = g.DriveGroup) as c
where g.DriveGroup is not null
and g.DriveGroup > 1
) x

这里是SQL Fiddle

我们建议您查看查询每一步的结果,看看实际情况是怎样的。