我有一张表格,其中包含以下数据。
Employee TimeRegister1 TimeRegister2 TimeRegister3 TimeRegister4
77 2014-04-01 11:51:43.000 2014-04-01 14:03:52.000 2014-04-01 14:17:01.000 2014-04-01 16:01:12.000
77 2014-04-03 09:48:33.000 2014-04-03 12:13:43.000 2014-04-03 12:22:27.000 2014-04-03 14:03:43.000
181 2014-04-02 08:24:34.000 2014-04-02 13:01:10.000 2014-04-02 14:30:31.000 2014-04-02 18:04:04.000
我需要的是在另一列上写下每个员工每天从每对列(奇数减去偶数)之间的差异计算的总数。
在上面的示例中,对于Employee 77 and 2014-04-01
,它应该在另一列上写下TimeRegister 2 - TimeRegister 1
,TimeRegister 4 - TimeRegister 3
之间差异的总和。
应该输出这样的东西(秒是无关紧要的,只需要几小时/分钟):
Employee TimeRegister1 TimeRegister2 TimeRegister3 TimeRegister4 CALCULATEDCOL
77 2014-04-01 11:51:43.000 2014-04-01 14:03:52.000 2014-04-01 14:17:01.000 2014-04-01 16:01:12.000 2014-04-01 03:56:00.000
除了TimeRegister
列最多可以达到30列(我只显示了4列但可能更多)所以我需要对每个奇数/偶数对进行有序计算,直到它用完列。
任何帮助我如何在SQL中实现这一点将不胜感激。感谢。
答案 0 :(得分:0)
假设所提供的表是正确的(即不是30列),您可以通过DATEDIFF
DateTimes,将差异加在一起,然后将它们添加回其中一个时间的基准日期来完成此操作(假设所有DateTime都在同一天)。您可以通过选择分钟作为差异/添加分辨率来消除秒数。要处理缺失的数据,每个ISNULL()
配对都需要COALESCE
或In / Out
。
SELECT Employee, TimeRegister1, TimeRegister2, TimeRegister3, TimeRegister4,
DATEADD(mi, ISNULL(DATEDIFF(mi, TimeRegister1, TimeRegister2), 0)
+ ISNULL(DATEDIFF(mi, TimeRegister3, TimeRegister4), 0),
CAST(CAST(TimeRegister1 AS DATE) AS DATETIME))
as CALCULATEDCOL
FROM TimeRegister;
根据评论,最好将CALCULATEDCOL
拆分为单独的日期和时间组件,因为根据情况,CALCULATEDCOL
根本不代表某个时间点。
如果您确实最多有30列,则需要对每对In/Out
数据重复计算(并希望员工每天不超过15次!)。< / p>
修改强>
要从时钟输入/输出数据的原始表中执行此操作,假设方向是可获得的(否则数据接下来是无用的),并丢弃员工在同一天没有连续输入和输出的任何数据,怎么样:
WITH cte AS
(
SELECT Employee,
TimeRegister,
Direction,
CAST(TimeRegister AS DATE) AS TheDate,
ROW_NUMBER() OVER (PARTITION BY Employee, CAST(TimeRegister AS DATE)
ORDER BY TimeRegister ASC) AS Rnk
FROM TimeRegister
)
SELECT
cur.Employee,
DATEADD(mi, SUM(DATEDIFF(mi, cur.TimeRegister, nxt.TimeRegister)),
CAST(cur.TheDate AS DATETIME)) AS CALCULATEDCOL
FROM cte cur
INNER JOIN cte nxt
ON cur.Employee = nxt.Employee
AND cur.TheDate = nxt.TheDate AND cur.Rnk + 1 = nxt.Rnk
WHERE cur.Direction = 'I' AND nxt.Direction = 'O'
GROUP BY cur.Employee, cur.TheDate;