在Sql查询中透视时间日志

时间:2016-07-18 08:22:58

标签: sql sql-server-2008-r2

我在查询我的timelogs表时有点困惑, 以下是样本数据:

TimelogId     EmployeeId     RecordDate     RecordTime     Type
---------     ----------     ----------     ----------     ----
   1              4          2016-07-01     07:18:37         1
   2              4          2016-07-01     12:03:14         2
   5              4          2016-07-01     12:08:02         1
   6              4          2016-07-01     18:02:03         2
   7              6          2016-07-19     07:24:15         1
   8              5          2016-07-19     07:26:03         1
   9              6          2016-07-19     12:15:26         2
   10             5          2016-07-19     12:35:17         2
   13             5          2016-07-19     12:36:14         1
   16             6          2016-07-19     12:45:45         1
   17             6          2016-07-19     17:10:22         2
   18             5          2016-07-19     18:43:09         2

所需的输出:

   Date      EmployeeId    Time_In      Time_Out      Time_In      Time_Out
  -------    ----------    --------     --------      -------      -------
2016-07-01       4         07:18:37     12:03:14      12:08:03    18:02:03
2016-07-19       6         07:24:15     12:15:26      12:45:45    17:10:22
2016-07-19       5         07:26:03     12:35:17      12:36:14    18:43:08

其中Type(1)=时间和Type(2)=超时。

员工必须在12nn注销,然后在几分钟后重新登录。

我尝试使用基于我在此阅读的先前问题的数据透视表。虽然这是我第一次尝试在表格中使用数据透视。

select 
*
FROM
(
  select 
  EmployeeID,
  RecordDate,
  RecordTime,
  Type
  from tblTimeLogs
) d
PIVOT(
  Max(RecordTime) <---- I think the problem is right around here
  FOR Type in ([1],[2]) <----- plus i can't seem to rename this column names maybe i'll read a little further on this.
) piv;                        

查询输出:

EmployeeID          RecordDate          1                2
----------          ----------        ------          ------
    4               2016-07-01       12:08:02        18:02:03
    5               2016-07-19       12:36:14        18:43:09
    6               2016-07-19       12:45:45        17:10:22
这可能吗?谢谢。 :D

修改

正如vercelli所建议的那样,另一种情况就是例如用户忘了他/她已经在几分钟前定时,所以她再次进入。 e.g。

TimelogId     EmployeeId     RecordDate     RecordTime     Type
---------     ----------     ----------     ----------     ----
   1              4          2016-07-01     07:18:37         1
   2              4          2016-07-01     12:03:14         2
   5              4          2016-07-01     12:08:02         1
   6              4          2016-07-01     18:02:03         2
   7              6          2016-07-19     07:24:15         1
   8              5          2016-07-19     07:26:03         1
   9              6          2016-07-19     12:15:26         2
   10             5          2016-07-19     12:35:17         2
   13             5          2016-07-19     12:36:14         1
   16             6          2016-07-19     12:45:45         1
   17             6          2016-07-19     17:10:22         2
   18             5          2016-07-19     18:43:09         2
   19             5          2016-07-20     08:13:35         1  <--- Time in
   20             5          2016-07-20     08:14:35         1  <--- Timed In again
   21             5          2016-07-20     12:15:12         2  <--- Time Out

我尝试使用Vercelli先生的询问:

select 
EmployeeID as Emp, RecordDate, [1] as Time_In1, [2] as Time_Out1, [3] as Time_In2, [4] as Time_out2
FROM
(
  select 
  EmployeeID,
  RecordDate,
  RecordTime,
  ROW_NUMBER () over (partition by EmployeeId, RecordDate order by RecordTime, type) as rn
from tblTimeLogs
) d
PIVOT(
  max(RecordTime)
  FOR rn in ([1],[2],[3],[4])
) as piv;  

输出新查询:

 Emp   RecordDate    Time_In1    Time_Out1    Time_In2     Time_Out2
 ----  ----------    ---------   ---------    --------     ---------
  4    2016-07-01    07:18:37    12:03:14     12:08:02     18:02:03
  5    2016-07-19    07:26:03    12:35:17     12:36:14     18:43:09
  5    2016-07-20    08:13:35    08:14:35     12:15:12       Null <--- the problem is right around this portion
  6    2016-07-19    07:24:15    12:15:26     12:45:45     17:10:22

预期产出:

  Emp   RecordDate    Time_In1    Time_Out1    Time_In2    Time_Out2
 ----  ----------    ---------   ---------    --------     ---------
  4    2016-07-01    07:18:37    12:03:14     12:08:02     18:02:03
  5    2016-07-19    07:26:03    12:35:17     12:36:14     18:43:09
  5    2016-07-20    08:13:35    12:15:12     08:14:35       Null <--- the second time in would fall on the second 5th column (Time_In2) since the **Type** value is = 1      
  6    2016-07-19    07:24:15    12:15:26     12:45:45     17:10:22

感谢帮助人员:D。我正在从这个问题中学习新事物。

2 个答案:

答案 0 :(得分:0)

我认为这就是你要找的东西。 Demo

select 
EmployeeID as Emp, RecordDate, [1] as Time_In1, [2] as Time_Out1, [3] as Time_In2, [4] as Time_out2
FROM
(
  select 
  EmployeeID,
  RecordDate,
  RecordTime,
  ROW_NUMBER () over (partition by EmployeeId, RecordDate order by RecordTime, type) as rn
  from tblTimeLogs
) d
PIVOT(
  max(RecordTime)
  FOR rn in ([1],[2],[3],[4])
) as piv;  

<强> OUPUT

Emp RecordDate  Time_In1    Time_Out1   Time_In2    Time_out2
4   2016-07-01  07:18:37    12:03:14    12:08:02    18:02:03
5   2016-07-19  07:26:03    12:35:17    12:36:14    18:43:09
6   2016-07-19  07:24:15    12:15:26    12:45:45    17:10:22

答案 1 :(得分:0)

hrmrmstr

---表创建脚本

 create table #test
   (
   employeeid int,
   recorddate date,
   recordtime time,
   typee int
   )

insert into #test  values(    4 ,         '2016-07-01',     '07:18:37',         1)
insert into #test  values(    4 ,         '2016-07-01',     '12:03:14',         2)
insert into #test  values(    4 ,         '2016-07-01',     '12:08:02',         1)
insert into #test  values(    4 ,         '2016-07-01',     '18:02:03',         2)

查询

 ;with cte
 as
 (
select
 employeeid,
 max(recorddate) as recorddate,
 min(recordtime) as timein,
max(recordtime) as Timein1 ,
 lead(min(recordtime)) over (partition by employeeid order by min(recordtime)) as 'timeout1',
 lead(max(recordtime)) over (partition by employeeid order by max(recordtime)) as 'timeout2'
 from #test
 group by 
 employeeid,typee
)
    select employeeid,recorddate,timein,timeout1,timein1,timeout2
    from cte
    where timeout1 is not null and timeout2 is not null