select employeeid, in_out,ondate
from emp_reporting
where employeeid = 121
employeeid in_out ondate
121 IN 2014-11-14 20:00:00.000
121 OUT 2014-11-13 15:15:00.000
121 IN 2014-11-13 20:24:00.000
121 OUT 2014-11-14 06:24:00.000
121 IN 2014-11-14 14:21:00.000
121 OUT 2014-11-14 14:22:00.000
我需要在首次登录时获得上述结果&最后一次注销转移明智,如10:00AM TO 6:00PM
和06:00AM TO 2:00PM
以及02:00PM TO 10:00PM
如何编写此类查询?
答案 0 :(得分:0)
DECLARE @T1 TABLE(EID INT,in_out VARCHAR(10),ondate DATETIME)
INSERT INTO @T1(EID,in_out,ondate) VALUES
(121,'IN','2014-11-14 20:00:00.000'),
(121,'OUT','2014-11-13 15:15:00.000'),
(121,'IN','2014-11-13 20:24:00.000'),
(121,'OUT','2014-11-14 06:24:00.000'),
(121,'IN','2014-11-14 14:21:00.000'),
(121,'OUT','2014-11-14 14:22:00.000')
SELECT EID,CONVERT(VARCHAR,ondate,106) AS OnDate,
RIGHT(CONVERT(VARCHAR, MIN(ondate), 100),7)+'-'+RIGHT(CONVERT(VARCHAR, MAX(ondate), 100),7) AS TIME
FROM @T1
GROUP BY EID,CONVERT(VARCHAR,ondate,106)
结果
EID OnDate TIME
121 13 Nov 2014 3:15PM- 8:24PM
121 14 Nov 2014 6:24AM- 8:00PM
OR
SELECT ISNULL(a.EID,b.EID)AS EID,ISNULL(CONVERT(VARCHAR, a.ondate, 106),'_')+'-'+ISNULL(CONVERT(VARCHAR, b.ondate, 106),'_')AS Ondate,ISNULL(RIGHT(CONVERT(VARCHAR, a.ondate, 100),7),'_') + ' - ' +ISNULL(RIGHT(CONVERT(VARCHAR, b.ondate, 100),7),'_') AS [Time] FROM
(SELECT ROW_NUMBER()OVER(ORDER BY ondate)AS ID,EID,ondate FROM @T1 WHERE in_out='IN' )a FULL JOIN
(SELECT ROW_NUMBER()OVER(ORDER BY ondate) AS ID,EID,ondate FROM @T1 WHERE in_out='OUT' )b ON a.EID=b.EID AND a.ondate<b.ondate
结果
EID Ondate Time
121 _-13 Nov 2014 _ - 3:15PM
121 13 Nov 2014-14 Nov 2014 8:24PM - 6:24AM
121 13 Nov 2014-14 Nov 2014 8:24PM - 2:22PM
121 14 Nov 2014-14 Nov 2014 2:21PM - 2:22PM
121 14 Nov 2014-_ 8:00PM - _
答案 1 :(得分:0)
由于我们无法保证每个人都有相应的出局,我们必须要有点防守:
with ordered_punches as (
select *,
row_number() over (partition by employeeid, in_out order by outdate) as [n],
row_number() over (partition by employeeid, in_out order by outdate desc) as [x],
from emp_reporting
)
select *
from ordered_punches
where in_out = 'IN'
and n = 1 --the earliest "IN" row
union all
select *
from ordered_punches
where in_out = 'OUT'
and x = 1 --the latest "OUT" row
如果输入和输出需要在输出的同一行中,我将它作为练习留给读者。
答案 2 :(得分:0)
我理解你的目标 - 在同一行显示工作班次的开始和结束时间
下一个查询将执行此操作,如果错过了一些工作时间戳,将显示NULL
DECLARE @EmpID INT = 121
SELECT CASE WHEN inw.EmployeeId IS NULL THEN
outw.EmployeeId ELSE inw.EmployeeId END AS EmployeeID
, inw.OnDate AS 'Started'
, outw.OnDate AS 'Finished'
, ISNULL(CONVERT(VARCHAR, inw.OnDate, 0), 'n/a')
+ ' - ' +
ISNULL(CONVERT(VARCHAR, outw.OnDate, 0), 'n/a') AS 'WorkShift'
FROM (
SELECT w.EmployeeID
, w.OnDate
, (SELECT MIN(OnDate)
FROM Worktime
WHERE EmployeeId = w.EmployeeId
AND In_Out = 'OUT'
AND OnDate >w.OnDate) AS 'Finished'
FROM Worktime w
WHERE w.EmployeeId = @EmpID AND w.In_Out = 'IN') inw
FULL OUTER JOIN (
SELECT w.EmployeeID
, w.OnDate
, (SELECT MAX(OnDate)
FROM Worktime
WHERE EmployeeId = w.EmployeeId
AND In_Out = 'IN'
AND OnDate < w.OnDate) AS 'Started'
FROM Worktime w
WHERE w.EmployeeId = @EmpID AND w.In_Out = 'OUT') outw
ON outw.EmployeeId = inw.EmployeeId AND outw.Started = inw.OnDate
ORDER BY Started