任何人都可以帮忙吗?我们的考勤系统会生成以下数据:
Empid Department Timestamp Read_ID
3221 IT 2017-01-29 11:12:00.000 1
5565 IT 2017-01-29 12:28:06.000 1
5565 IT 2017-01-29 12:28:07.000 1
3221 IT 2017-01-29 13:12:00.000 2
5565 IT 2017-01-29 13:28:06.000 2
3221 IT 2017-01-30 07:42:15.000 1
3221 IT 2017-01-30 16:16:15.000 2
3221 IT 2017-01-31 09:05:00.000 1
3221 IT 2017-01-31 11:05:00.000 2
3221 IT 2017-01-31 13:20:00.000 1
3221 IT 2017-01-31 16:10:00.000 2
其中Read_ID值为:
1
=条目2
=退出我正在寻找要在MS SQL 2014上运行的SQL查询,例如,汇总每个员工每月的出勤时间
Empid Department Year Month TotalHours
3221 IT 2017 1 15:24
5565 IT 2017 1 01:00
答案 0 :(得分:2)
此查询应为您提供所需的结果。它的工作方式是选择每个条目,然后将其与同一员工的下一个退出一起加入(忽略没有进一步退出的条目):这为我们提供了该员工轮班的时间。然后汇总结果并在每个组中汇总轮班时间。
SELECT
t1.empid,
t1.department,
YEAR(t1.timestamp) Year,
MONTH(t1.timestamp) Month,
CONVERT(
varchar(12),
DATEADD(minute, SUM(DATEDIFF(minute, t1.timestamp, t2.timestamp)), 0),
114
) TotalHours
FROM
mytable t1
INNER JOIN mytable t2
ON t1.empid = t2.empid
AND t2.read_id = 2
AND t2.timestamp = (
SELECT MIN(timestamp)
FROM mytable
WHERE
read_id = 2
AND empid = t2.empid
AND timestamp > t1.timestamp
)
WHERE
t1.read_id = 1
GROUP BY t1.empid, t1.department, YEAR(t1.timestamp), MONTH(t1.timestamp)
ORDER BY 1, 2, 3, 4
返回:
empid | department | Year | Month | TotalHours ----: | :--------- | ---: | ----: | :----------- 3221 | IT | 2017 | 1 | 15:24:00:000 5565 | IT | 2017 | 1 | 02:00:00:000
DB Fiddle demo on SQL Server 2014
但是,在极端情况下,员工输入两次然后存在(这种情况发生在您的数据中,员工5565
在29/01/2017 12:28:06
输入,而{em>在输入{1}},然后在29/01/2017 12:28:07
退出,上面的查询将考虑两个重叠的条目,并将它们映射到同一出口,导致这一小时的工作被计算两次。
这与您的预期结果相符,但这是您真正想要的吗?这是另一种查询,如果连续出现多个相同的雇员条目,则仅考虑最新的一个:
29/01/2017 13:28:06
返回:
empid | department | Year | Month | TotalHours ----: | :--------- | ---: | ----: | :----------- 3221 | IT | 2017 | 1 | 15:24:00:000 5565 | IT | 2017 | 1 | 01:00:00:000
答案 1 :(得分:1)
尝试一下。我不确定哪种时间格式可以满足您的系统要求,所以我将两者放在同一位置:
SELECT * INTO #Tbl3 FROM (VALUES
(3221,'IT','2017-01-29 11:12:00.000',1),
(5565,'IT','2017-01-29 12:28:06.000',1),
(5565,'IT','2017-01-29 12:28:07.000',1),
(3221,'IT','2017-01-29 13:12:00.000',2),
(5565,'IT','2017-01-29 13:28:06.000',2),
(3221,'IT','2017-01-30 07:42:15.000',1),
(3221,'IT','2017-01-30 16:16:15.000',2),
(3221,'IT','2017-01-31 09:05:00.000',1),
(3221,'IT','2017-01-31 11:05:00.000',2),
(3221,'IT','2017-01-31 13:20:00.000',1),
(3221,'IT','2017-01-31 16:10:00.000',2))
x (Empid,Department,Timestamp,Read_ID)
;With cte as (
SELECT t1.Empid, t1.Department
, [Year] = Year(t1.Timestamp)
, [Month] = Month(t1.Timestamp)
, Seconds = SUM(DATEDIFF(second, t1.Timestamp, t2.Timestamp))
FROM #Tbl3 as t1
OUTER APPLY (
SELECT Timestamp = MIN(t.Timestamp)
FROM #Tbl3 as t
WHERE t.Department = t1.Department and t.Empid = t1.Empid
and t.Timestamp > t1.Timestamp and t.Read_ID = 2
) as t2
WHERE t1.Read_ID = 1
GROUP BY t1.Empid, t1.Department, Year(t1.Timestamp), Month(t1.Timestamp))
SELECT *, TotalHours = Seconds / 3600., TotalTime =
RIGHT('0'+CAST(Seconds / 3600 as VARCHAR),2) + ':' +
RIGHT('0'+CAST((Seconds % 3600) / 60 as VARCHAR),2) + ':' +
RIGHT('0'+CAST(Seconds % 60 as VARCHAR),2)
FROM cte;