当我必须对数据进行非规范化时,我喜欢使用自联接。我已经在 SQL Server 2012 上测试了以下内容。(但是,一般方法应该适用于任何支持自连接的 SQL RDBS,但您必须根据具体情况修改 DATETIME2 数据类型和函数调用。)
数据:
DECLARE @t1 AS TABLE (
Day1 DATE
,Staff VARCHAR(3)
,Login DATETIME2
,Logout DATETIME2
);
INSERT INTO @t1
VALUES ('20130704', '123', '20130704 18:44:16.533', '20130704 00:00:00.000')
,('20130706', '456', '20130706 00:00:00.000', '20130706 01:10:12.000')
,('20130704', '123', '20130704 00:00:00.000', '20130704 20:24:16.553')
,('20130704', '123', '20130704 20:44:16.533', '20130704 00:00:00.000')
,('20130704', '123', '20130704 00:00:00.000', '20130704 22:54:16.553')
,('20130705', '456', '20130705 08:45:12.550', '20130705 00:00:00.000');
解决方案:
SELECT a.Day1, a.Staff, a.Login, MIN(b.Logout) AS Logout,
DateDiff(minute, a.login, MIN(b.logout)) AS Elapsed
FROM @t1 a join @t1 b
ON a.Staff = b.Staff AND a.Login < b.Logout AND CONVERT(TIME, a.Login) > '00:00:00.00'
GROUP BY a.Day1, a.Staff, a.Login;
补充说明:
- 您提到您必须计算小时数。这可以在同一个查询中完成。在这种情况下,“已用”列计算分钟数。 (根据您的目的将
DateDiff 的第一个参数更改为hour。)
@戈登林诺夫
- 如果登录是一天而注销是另一天,查询会正确处理情况。