查询工作时间

时间:2015-11-11 12:57:47

标签: sql sql-server sql-server-2008

我有一个查询,让员工上班/下班时间,并将他们分组为夜班,所以第一个记录是前一晚

此查询的结果是

        Name    ID          CardCode Telephone  EndOverDay          T                   Day  DayNumber InDay
        Name    Pen-005731  0042f55c    8           1       2015-11-02 19:42:12.000 2015.11.02  42309   1
        Name    Pen-005731  0042f55c    8           1       2015-11-03 01:12:08.000 2015.11.03  42309   2
        Name    Pen-005731  0042f55c    8           1       2015-11-03 01:41:43.000 2015.11.03  42309   3
        Name    Pen-005731  0042f55c    8           1       2015-11-03 07:47:25.000 2015.11.03  42309   4
        Name    Pen-005731  0042f55c    8           1       2015-11-03 19:44:02.000 2015.11.03  42310   1
        Name    Pen-005731  0042f55c    8           1       2015-11-04 01:00:01.000 2015.11.04  42310   2
        Name    Pen-005731  0042f55c    8           1       2015-11-04 01:26:30.000 2015.11.04  42310   3
        Name    Pen-005731  0042f55c    8           1       2015-11-04 07:55:55.000 2015.11.04  42310   4
        Name    Pen-005731  0042f55c    8           1       2015-11-04 19:42:51.000 2015.11.04  42311   1
        Name    Pen-005731  0042f55c    8           1       2015-11-05 01:08:35.000 2015.11.05  42311   2
        Name    Pen-005731  0042f55c    8           1       2015-11-05 01:36:20.000 2015.11.05  42311   3
        Name    Pen-005731  0042f55c    8           1       2015-11-05 07:49:14.000 2015.11.05  42311   4
        Name    Pen-005731  0042f55c    8           1       2015-11-05 19:42:37.000 2015.11.05  42312   1
        Name    Pen-005731  0042f55c    8           1       2015-11-06 01:17:05.000 2015.11.06  42312   2
        Name    Pen-005731  0042f55c    8           1       2015-11-06 01:45:44.000 2015.11.06  42312   3
        Name    Pen-005731  0042f55c    8           1       2015-11-06 07:45:56.000 2015.11.06  42312   4
        Name    Pen-005731  0042f55c    8           1       2015-11-09 19:39:21.000 2015.11.09  42316   1
        Name    Pen-005731  0042f55c    8           1       2015-11-10 01:11:15.000 2015.11.10  42316   2
        Name    Pen-005731  0042f55c    8           1       2015-11-10 01:36:39.000 2015.11.10  42316   3
        Name    Pen-005731  0042f55c    8           1       2015-11-10 07:57:02.000 2015.11.10  42316   4
        Name    Pen-005731  0042f55c    8           1       2015-11-10 19:42:45.000 2015.11.10  42317   1
        Name    Pen-005731  0042f55c    8           1       2015-11-11 01:16:07.000 2015.11.11  42317   2
        Name    Pen-005731  0042f55c    8           1       2015-11-11 01:40:06.000 2015.11.11  42317   3
        Name    Pen-005731  0042f55c    8           1       2015-11-11 07:55:20.000 2015.11.11  42317   4

T是记录的时间日期 Inday是滑动的顺序

我需要获取每个DayNumber的时间,因此对于daynumber 42317

在Inday 1和inday 2之间的柱子之间是Datediff,然后是3 -4然后加入togeather得到的总时间

这是我到目前为止所拥有的

        WITH ByDays AS ( 
            SELECT     CHINA_VISION_PubPersonnel.Name, CHINA_VISION_PubPersonnel.ID, CHINA_VISION_PubCards.CardCode, CHINA_VISION_PubPersonnel.Telephone, ATDShiftDetail.EndOverDay, 
                                  CHINA_VISION_DorEvents.EventTM AS T, CONVERT(VARCHAR(10), CHINA_VISION_DorEvents.EventTM, 102) AS Day, 
                                  FLOOR(CONVERT(FLOAT, DATEADD(hour, 5, EventTM))) AS DayNumber,    
                                  ROW_NUMBER() OVER(PARTITION BY FLOOR(CONVERT(FLOAT,FLOOR(CONVERT(FLOAT, DATEADD(hour, 6, EventTM))))) ORDER BY FLOOR(CONVERT(FLOAT, DATEADD(hour, 5, EventTM)))) InDay  
            FROM         CHINA_VISION_PubCards INNER JOIN
                                  CHINA_VISION_PubPersonnel ON CHINA_VISION_PubCards.PubPersonnel_Ref = CHINA_VISION_PubPersonnel.Reference INNER JOIN
                                  CHINA_VISION_DorEvents ON CHINA_VISION_PubCards.CardCode = CHINA_VISION_DorEvents.CardCode INNER JOIN
                                  ATDShiftDetail ON RIGHT(CHINA_VISION_PubPersonnel.ID, 4) = ATDShiftDetail.Name
            WHERE     (CHINA_VISION_DorEvents.DorCtrls_Ref = '16') AND (CHINA_VISION_DorEvents.CardCode = '0042f55c') AND (CONVERT(Date, CHINA_VISION_DorEvents.EventTM) 
                                  > DATEADD(day,-10, GETDATE())) AND ATDShiftDetail.EndOverDay = '1'


                )
                , Diffs AS (            
                SELECT 
                    EvenRow.Day,EvenRow.DayNumber, OddRow.ID, OddRow.name , OddRow.CardCode , OddRow.Telephone ,EvenRow.EndOverDay ,
                    EvenRow.T ET, OddRow.T OT, OddRow.T-EvenRow.T Diff, 
                    DATEDIFF(S,EvenRow.T,OddRow.T) DiffSeconds -- difference in seconds
                FROM 
                    (SELECT BE.T, BE.Day, BE.InDay, BE.ID , BE.Name , Be.CardCode, BE.Telephone, BE.EndOverDay, BE.DayNumber
                     FROM ByDays BE) EvenRow -- Even rows
                INNER JOIN
                    (SELECT BO.T, BO.Day, BO.InDay , BO.ID , BO.Name , BO.CardCode, BO.Telephone, BO.EndOverDay
                     FROM ByDays BO) OddRow -- Odd rows
                ON EvenRow.InDay = OddRow.InDay +1 -- Join rows (1,2), (3,4) and so on
                   AND EvenRow.Day = OddRow.Day --  in the same day
                )


                SELECT
                    Name,
                    CardCode,
                    ID,
                    Telephone,
                    EndOverDay,
                    MIN(Day),
                    DayNumber,
                    SUM(DiffSeconds) Seconds, 
                    CONVERT(VARCHAR(8), 
                    (DATEADD(S, SUM(DiffSeconds), '1900-01-01T00:00:00')),
                    108) TotalHHMMSS -- The same, formatted as HH:MM:SS
                FROM Diffs GROUP BY DayNumber,  ID , CardCode, Name, Telephone,EndOverDay
                ORDER BY DayNumber  

这会产生这样的结果。

        Name    CardCode          ID    Telephone   EndOverDay      Day  DayNumber  Seconds TotalHHMMSS
        Name    0042f55c    Pen-005731      8           1       2015.11.03  42309   42997   11:56:37
        Name    0042f55c    Pen-005731      8           1       2015.11.04  42310   42416   11:46:56
        Name    0042f55c    Pen-005731      8           1       2015.11.05  42311   42803   11:53:23
        Name    0042f55c    Pen-005731      8           1       2015.11.06  42312   -23331  17:31:09
        Name    0042f55c    Pen-005731      8           1       2015.11.10  42316   42343   11:45:43
        Name    0042f55c    Pen-005731      8           1       2015.11.11  42317   -23953  17:20:47

正如您所看到的那样,正确的时间不是Datdiffed,因为根据提供的数据结果不正确

1 个答案:

答案 0 :(得分:2)

寻找这个?

create table punch (
    Name nvarchar(50),
    Id nvarchar(50),
    CardCode nvarchar(50),
    TelephoneEnd int,
    OverDay int,
    T datetime,
    punchDate datetime,
    DayNumber int,
    InDay int )


insert into punch 
select 'Hame',    'Pen-005731',  '0042f55c',    8,           1,   '2015-11-09 19:39:21.000', '2015.11.09',  42316,   1 union all
select 'Hame',    'Pen-005731',  '0042f55c',    8,           1,   '2015-11-10 01:11:15.000', '2015.11.10',  42316,   2 union all
select 'Hame',    'Pen-005731',  '0042f55c',    8,           1,   '2015-11-10 01:36:39.000', '2015.11.10',  42316,   3 union all
select 'Hame',    'Pen-005731',  '0042f55c',    8,           1,   '2015-11-10 07:57:02.000', '2015.11.10',  42316,   4 union all
select 'Hame',    'Pen-005731',  '0042f55c',    8,           1,   '2015-11-10 19:42:45.000', '2015.11.10',  42317,   1 union all
select 'Hame',    'Pen-005731',  '0042f55c',    8,           1,   '2015-11-11 01:16:07.000', '2015.11.11',  42317,   2 union all
select 'Hame',    'Pen-005731',  '0042f55c',    8,           1,   '2015-11-11 01:40:06.000', '2015.11.11',  42317,   3 union all
select 'Hame',    'Pen-005731',  '0042f55c',    8,           1,   '2015-11-11 07:55:20.000', '2015.11.11',  42317,   4 

select sum(x.minutesPunched)/60 as hoursWorked,
       sum(x.minutesPunched) % 60 as minutesWorked
  from (
        select datediff(mi, p2.T, p1.T) as minutesPunched
          from punch p1
          inner join punch p2 on p1.DayNumber = p2.DayNumber and p1.InDay = p2.InDay + 1
       ) x

分组删除2-3个aggs:

select sum(x.minutesPunched)/60 as hoursWorked,
       sum(x.minutesPunched) % 60 as minutesWorked,
       x.DayNumber
  from (
        select datediff(mi, p1.T, p2.T) as minutesPunched,
               p1.DayNumber
          from punch p1
          inner join punch p2 on p1.DayNumber = p2.DayNumber and p1.InDay = p2.InDay - 1
          where (p1.InDay + 1) % 2 = 0
       ) x
 group by x.DayNumber