在sql中,日期和时间不合适?

时间:2017-12-09 13:50:42

标签: sql sql-server tsql

Sql Fiddle Demo

当我更改这样的表数据时,意味着结果将被更改。

INSERT INTO Table1
    ([id], [time_stamp], [AccessType])
VALUES
    (1001, '2017-09-05 09:35:00', 'IN'),
      (1001, '2017-09-05 09:37:00', 'IN'),
       (1001, '2017-09-05 09:38:00', 'IN'),
    (1002, '2017-09-05 11:00:00', 'IN'),
    (1001, '2017-09-05 12:00:00', 'OUT'),
     (1001, '2017-09-05 12:01:00', 'OUT'),
      (1001, '2017-09-05 12:02:00', 'OUT'),
    (1002, '2017-09-05 12:25:00', 'OUT'),
    (1001, '2017-09-05 13:00:00', 'IN'),
    (1002, '2017-09-05 14:00:00', 'IN'),
    (1001, '2017-09-05 17:00:00', 'OUT'),
    (1002, '2017-09-05 18:00:00', 'OUT');

我想要一个这样的确切结果:

id      check_in    check_out  totalhrs  check_in check_out totalhrs  date           
    1001     09:35       12:00      2:25       13:00    17:00     2:00    2013-09-05       
    1002     11:00       12:25      1:25       14:00    18:00     4:00    2013-09-05  

2 个答案:

答案 0 :(得分:1)

你可以试试这个。

;WITH CTE AS
(
    SELECT *, 
        GRP = ROW_NUMBER() OVER(PARTITION BY id, CAST( [time_stamp] AS date )  ORDER BY time_stamp)
              - ROW_NUMBER() OVER(PARTITION BY id,CAST( [time_stamp] AS date ) , [AccessType] ORDER BY time_stamp)
    FROM table1 
)
, CTE2 AS (
    SELECT 
        [id]
        , MIN(CAST( [time_stamp] AS time )) MinTime
        , CAST( [time_stamp] AS date ) [date]
        , CASE [AccessType] WHEN 'IN' THEN 'check_in_' ELSE 'check_out_' END 
            + CAST(ROW_NUMBER() OVER(PARTITION  BY id, [AccessType] ORDER BY GRP) AS varchar) ColHeader
    FROM CTE 
    GROUP BY 
        id 
        , [AccessType]
        , GRP 
        , CAST( [time_stamp] AS date )
)
SELECT 
    id
    , [check_in_1] check_in
    , [check_out_1] check_out  
    , CAST( DATEADD(MINUTE, DATEDIFF(MINUTE, [check_in_1] , [check_out_1]), '00:00') AS time) totalhrs  
    , [check_in_2] check_in
    , [check_out_2] check_out   
    , CAST( DATEADD(MINUTE, DATEDIFF(MINUTE, [check_in_2] , [check_out_2]), '00:00') AS time) totalhrs 
    , [date]  FROM CTE2
PIVOT (MIN(MinTime) FOR ColHeader IN ([check_in_1], [check_out_1], [check_in_2], [check_out_2])) PVT

结果:

id          check_in         check_out        totalhrs         check_in         check_out        totalhrs         date
----------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ----------
1001        09:35:00         12:00:00         02:25:00         13:00:00         17:00:00         04:00:00         2017-09-05
1002        11:00:00         12:25:00         01:25:00         14:00:00         18:00:00         04:00:00         2017-09-05

答案 1 :(得分:1)

也可以尝试:

select
       id, cast(time_stamp as date) [date]
     , format(max(case when in_rank = 1 then time_stamp end),'HH:mm')         check_in_1
     , format(max(case when in_rank = 1 then next_timestamp end),'HH:mm')     check_out_1
     , format(max(case when in_rank = 1 then 
           dateadd(ss,datediff(ss,time_stamp,next_timestamp),0) end),'HH:mm') total_hrs_1
     , format(max(case when in_rank = 2 then time_stamp end),'HH:mm')         check_in_2
     , format(max(case when in_rank = 2 then next_timestamp end),'HH:mm')     check_out_2
     , format(max(case when in_rank = 2 then
           dateadd(ss,datediff(ss,time_stamp,next_timestamp),0) end),'HH:mm') total_hrs_2

from (
      select
            id, time_stamp, AccessType, next_timestamp, next_accesstype
          , dense_rank() over(partition by id, cast(time_stamp as date) order by time_stamp) in_rank
      from @tempProcesstable t1
      outer apply (
          select top(1) t2.DT, t2.EVENTID
          from trnevents t2
          where t1.id = t2.emp_reader_id and t1.AccessType <> t2.EVENTID
          and cast(t1.time_stamp as date) = cast(t2.DT as date)
          and t1.time_stamp < t2.DT
          order by t2.DT
          ) oa (next_timestamp, next_accesstype)
      where AccessType = 'IN'
     ) d
group by id, cast(time_stamp as date)