按工作日分隔时间间隔

时间:2016-12-12 21:12:37

标签: sql ms-access

我有下表(但有更多数据):

Workcenter ID | Status | Start Date/Time | End Date/Time SLX83D Breakdown 11/27/2016 16:00:00 11/29/2016 12:30:00 SLX83C No Operator 11/27/2016 6:40:00 11/27/2016 13:00:00 SLX83A QA Inspection 11/28/2016 13:00:00 11/28/2016 14:00:00 SLX83A QA Inspection 11/28/2016 15:00:00 11/28/2016 16:00:00

我想将工作日的状态时间间隔(即12/1 6 am到12/2 6 am)和总和分开。

我的想法是按以下格式创建交叉表查询:

Work Day | Workcenter ID | Breakdown | No Operator | QA Inspection 11/27/2016 SLX83D 14:00:00 11/28/2016 SLX83D 24:00:00 11/29/2016 SLX83D 6:30:00 11/27/2016 SLX83C 6:20:00 11/28/2016 SLX83A 2:00:00

无法确定如何使其发挥作用,我对其他想法持开放态度。

P.S。 我的表中还有以下列:开始日期,开始时间,结束日期和结束时间。 (这些用于计算'开始日期/时间'和'结束日期/时间'

我是Access的新手,对SQL几乎一无所知,谢谢。

编辑: 通过在表格中创建以下计算列,我能够找到给定日期的状态:

在日期之间: IIf([Start Date/Time]>= "11/28/2016 06:00:00" And [End Date/Time]<= "11/29/2016 06:00:00" ,[End Date/Time]-[Start Date/Time],0)*24*60

在日期之前开始: IIf([Start Date/Time]< "11/28/2016 06:00:00" And [End Date/Time]>= "11/28/2016 06:00:00" And [End Date/Time]<= "11/29/2016 06:00:00" ,[End Date/Time]- "11/28/2016 06:00:00" ,0)*24*60

结束日期: IIf([End Date/Time]> "11/28/2016 06:00:00" And [Start Date/Time]>= "11/28/2016 06:00:00" And [Start Date/Time]<= "11/29/2016 06:00:00" , "11/29/2016 06:00:00" -[Start Date/Time],0)*24*60

跨越整个日期: IIf([Start Date/Time]< "11/28/2016 06:00:00" And [End Date/Time]> "11/29/2016 06:00:00" ,1,0)*24*60

对这些列进行求和可得出给定工作中心在给定日期具有给定状态的总分钟数 但是,这仅适用于一次一个工作日。我更愿意弄清楚如何使用SQL来获得结果,如上表中的工作日历史。

Workcenter ID | Status | Start Date/Time | End Date/Time SLX83D Breakdown 11/27/2016 16:00:00 11/29/2016 12:30:00 SLX83A QA Inspection 11/28/2016 13:00:00 11/28/2016 14:00:00 SLX83A QA Inspection 11/28/2016 15:00:00 11/28/2016 16:00:00

Workcenter ID | IBD | SBD | EAD | SWD | SUM SLX83D 1440 1440 (24 hrs) SLX83A 60 60 (1 hr) SLX83A 60 60 (These 2 hrs would have to be summed later somehow, this isn't a great solution)

编辑2: 我尝试了以下但无法让它工作。 (学分归于:https://social.msdn.microsoft.com/Forums/sqlserver/en-US/cca28ddd-2041-4504-b602-3bedd9ca704e/counts-by-time-interval?forum=transactsql#208e97ad-11a7-4d96-9436-c82612755d46

SELECT DatePart(Day,[Start Date/Time]) AS [Workday Date], Count([Status Table].[Workcenter ID]) AS [Workday Interval]

FROM [Status Table]

WHERE ((([Status Table].[Start Date/Time]) Between [Start Date/Time] And [End Date/Time]))

GROUP BY DatePart(Day,interval);

1 个答案:

答案 0 :(得分:2)

考虑在多个阶段处理您的需求:

  1. 建立所有可能工作日开始(第一天上午6:00)和结束点(第二天上午5:59)的时间表表。如果天数达到数百或数千,则可能需要使用VBA循环动态创建新表(TableDef)从最早到最晚的日期。

    Schedule Table

  2. 结合所有三种可能持续时间的联盟查询:a)部分日开始; b)多个全天; c)部分日结束。每个都使用嵌套的IIF()逻辑来计算小时数。每个SELECT查询都将使用实际小时数表和计划表运行交叉连接和间隔过滤器。

  3. 通过工作日 ID 状态列旋转的转化输出中的汇总选项卡查询进行汇总。

  4. 联合查询 (请务必删除注释,不符合Access SQL查询语句。)

    -- ACTUAL START PARTIAL
    SELECT w.[Workcenter ID], w.Status, w.[StartDate/Time], w.[End Date/Time], 
           s.WorkStartDates, s.WorkEndDates,
           IIF(w.[StartDate/Time] >= s.WorkStartDates AND w.[End Date/Time] <= s.WorkEndDates,
             DateDiff('n', w.[StartDate/Time], w.[End Date/Time]), 
             IIF(w.[StartDate/Time] >= s.WorkStartDates AND w.[End Date/Time] >= s.WorkEndDates,
                 DateDiff('n', w.[StartDate/Time], s.WorkEndDates), NULL)) / 60 AS WorkHours
    FROM WorkCenterHours w, Schedule s
    WHERE w.[StartDate/Time] BETWEEN s.WorkStartDates AND s.WorkEndDates
    
    UNION
    
    -- ACTUAL START AND END ACROSS WORKDAYS
    SELECT w.[Workcenter ID], w.Status, w.[StartDate/Time], w.[End Date/Time], 
           s.WorkStartDates, s.WorkEndDates,
           DateDiff('n', s.WorkStartDates, s.WorkEndDates) / 60 As WorkHours
    FROM WorkCenterHours w, Schedule s
    WHERE s.WorkStartDates BETWEEN w.[StartDate/Time] AND w.[End Date/Time]
    AND s.WorkEndDates BETWEEN w.[StartDate/Time] AND w.[End Date/Time]
    
    UNION 
    
    -- ACTUAL END LEFTOVER
    SELECT w.[Workcenter ID], w.Status, w.[StartDate/Time], w.[End Date/Time],
           s.WorkStartDates, s.WorkEndDates,
           IIF(w.[StartDate/Time] <= s.WorkStartDates AND w.[End Date/Time] <= s.WorkEndDates,
             DateDiff('n', w.[End Date/Time], s.WorkEndDates), 
             IIF(w.[StartDate/Time] >= s.WorkStartDates AND w.[End Date/Time] <= s.WorkEndDates,
                 DateDiff('n', w.[StartDate/Time], w.[End Date/Time]), NULL)) / 60 AS WorkHours
    FROM WorkCenterHours w, Schedule s
    WHERE w.[End Date/Time] BETWEEN s.WorkStartDates AND s.WorkEndDates;
    

    Union Query

    交叉标签查询 (以上用作数据源)

    TRANSFORM Sum(q.WorkHours) AS SumOfWorkHours
    SELECT DateValue(q.WorkStartDates) AS WorkDate, q.[Workcenter ID]
    FROM UnionSourceQuery q
    GROUP BY DateValue(q.WorkStartDates), q.[Workcenter ID]
    PIVOT q.Status;
    

    Cross Tab

    注意:由于使用嵌套逻辑和各种日期函数调用的联合查询中的交叉连接过滤器,最终会进行轮转,因此无法保证性能,并且可能会因此解决方案的数据大小而有所不同。