如何积累值tsql II

时间:2014-06-29 17:24:41

标签: sql tsql sql-server-2012

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

我有像这个架构的数据:

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

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

   I have to search the BeginWorkDay first rest => 10 hours then
   BWD = BeginWorkDay
   EWD = EndWorkDay


   Do
     Compute how many minutes have the workDay (Diff between BWD and EWD) 
     SUM(DriveTime) as TotalDayDrive
     MAX(DriveTime) as MaxDriveDayPeriod
     SUM(Rest) as TotalDayRest
     Rest as NightRest
     MAX(Rest) as MaxDayRest
     Min(Rest) as MinDayRest
     SUM(TotalKM) as KM
   until next rest => 10 hours
   IF No More Rest EXIT DO
   Loop

Desired Result:

Driver     Plate    Begin Work Day            End Work Day             WorkDayTime(minu)
11953512       IVA870   2014-01-06 00:47:01.000   2014-01-06 11:08:32.000  621

DriveTime(seconds)   MaxDayDrive(sec)   TotalDayRest(minu)   NightRest(minu)   MinDayRest(minu)   
19081            3786               304              2.259             14              

MaxDayRest(minu)   KM
89                 138.200


DATA FILE                           
                Minutes Seconds 
DriverId   Plate   BeginDate    EndDate      NextBeginDate   Rest   DriveTime   DriveKM
11953512   IVA870  2014-01-04   2014-01-04   2014-01-06      2.259  2038    13.400
                   10:34:42.000 11:08:40.000 00:47:01.000    

11953512   IVA870  2014-01-06   2014-01-06   2014-01-06      89     2615    34.500
                   00:47:01.000 01:30:36.000 02:59:08.000   

11953512   IVA870  2014-01-06   2014-01-06   2014-01-06      51     2604    19.000
                   02:59:08.000 03:42:32.000 04:33:56.000

11953512   IVA870  2014-01-06   2014-01-06   2014-01-06      18     2294    17.500
                   04:33:56.000 05:12:10.000 05:30:42.000

11953512   IVA870  2014-01-06   2014-01-06   2014-01-06      47     2895    20.500
                   05:30:42.000 06:18:57.000 07:05:56.000    

11953512   IVA870  2014-01-06   2014-01-06   2014-01-06      47     2819    19.800
                   07:05:56.000 07:52:55.000 08:39:51.000   

11953512   IVA870  2014-01-06   2014-01-06   2014-01-06      14     239         0.300
                   08:39:51.000 08:43:50.000 08:57:05.000    

11953512   IVA870  2014-01-06   2014-01-06   2014-01-06      38     3786    18.000
                   08:57:05.000 10:00:11.000 10:38:03.000

11953512   IVA870  2014-01-06   2014-01-06   2014-01-07     843     1829    8.900
                   10:38:03.000 11:08:32.000 01:11:04.000   

还有另一个主题"如何积累价值tsql"其中 Jerrad 编写了一个解决类似问题的魅力脚本,但我无法想象如何修改它来解决这个问题。

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

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

1 个答案:

答案 0 :(得分:1)

首先,您需要确定每天组成的行。我根据BeginDateNextBeginDate将您的数据表加入到自身中。这为您提供了每天的开始和结束日期时间。我将结果存储在CTE中。

;with cte
as(
    select d.DriverId, 
    d.Matricula, 
    d.BeginDate DayBeginDate,
    (select MAX(EndDate) from Drive d3 where d3.DriverId = d.DriverId and d3.EndDate < DATEADD(d, 1, DATEDIFF(d, 0, d.BeginDate))) DayEndDate
    from Drive d 
    join Drive d2 on d.BeginDate = d2.NextBeginDate
    where d2.Rest > 600
)

现在只需根据CTE中的开始和结束日期时间从主数据表中选择各种聚合。

select d.DriverId, 
d.Matricula, 
d.DayBeginDate, 
d.DayEndDate,
DATEDIFF(N, d.DayBeginDate, d.DayEndDate) WorkDayTime,
(select SUM(d2.DriveTime) from Drive d2 where d2.DriverId = d.DriverId and d2.BeginDate >= d.DayBeginDate and d2.EndDate <= d.DayEndDate) DriveTime,
(select MAX(d2.DriveTime) from Drive d2 where d2.DriverId = d.DriverId and d2.BeginDate >= d.DayBeginDate and d2.EndDate <= d.DayEndDate) MaxDayDrive,
(select SUM(d2.Rest) from Drive d2 where d2.DriverId = d.DriverId and d2.BeginDate >= d.DayBeginDate and d2.EndDate < d.DayEndDate) TotalDayRest,
DATEDIFF(N, (select MAX(d2.EndDate) from Drive d2 where d2.DriverId = d.DriverId and d2.EndDate < d.DayBeginDate), d.DayBeginDate) NightRest,
(select MIN(d2.Rest) from Drive d2 where d2.DriverId = d.DriverId and d2.BeginDate >= d.DayBeginDate and d2.EndDate < d.DayEndDate) MinDayRest,
(select MAX(d2.Rest) from Drive d2 where d2.DriverId = d.DriverId and d2.BeginDate >= d.DayBeginDate and d2.EndDate < d.DayEndDate) MaxDayRest,
(select SUM(d2.DriveKM) from Drive d2 where d2.DriverId = d.DriverId and d2.BeginDate >= d.DayBeginDate and d2.EndDate <= d.DayEndDate) KM
from cte d 
group by d.DriverId, d.Matricula, d.DayBeginDate, d.DayEndDate

SQL Fiddle