我的表中包含以下数据:
ID | JobNumber | UserID | Date | Task
1 1 user1 02/05/2014 08:00:00 Task 1
2 1 user1 02/05/2014 08:00:10 Task 2
3 1 user1 02/05/2014 08:00:20 Task 3
4 1 user1 02/05/2014 08:00:30 Task 4
5 1 user1 02/05/2014 08:00:40 Task 5
6 1 user1 02/05/2014 08:00:50 Task 6
7 2 user1 02/05/2014 09:00:00 Task 1
8 2 user1 02/05/2014 09:00:10 Task 2
9 3 user1 02/05/2014 09:15:00 Task 1
10 3 user1 02/05/2014 09:15:45 Task 2
11 1 user2 02/05/2014 09:02:10 Task 1
12 1 user2 02/05/2014 09:02:25 Task 2
13 1 user1 02/05/2014 12:00:00 Task 10
14 1 user1 02/05/2014 12:00:10 Task 11
我将每天运行一个查询,它将通过上述内容并计算出总数。我需要做的是为每个用户计算出他们在每个JobNumber上工作了多长时间,所以上面会给我以下内容:
UserId | JobNumber | TotalTime
user1 1 00:01:00
user1 2 00:00:10
user1 3 00:00:45
user2 1 00:00:15
我想知道是否使用rownumber然后减去该组的最大和最小日期,但不太确定我是如何做到的。
非常感谢任何帮助。
答案 0 :(得分:1)
你不必在这里使用行号。只需使用分组
select userid, jobnumber, cast(max(date)-min(date) as time)
from table1
group by userid, jobnumber
order by userid
答案 1 :(得分:1)
如果您可以使用格式为秒数:
select userid, jobnumber, datediff(second, min(date), max(date)) as TimeInSeconds
from table t
group by userid, jobnumber;
将其转换回时间格式取决于您使用的SQL Server版本。
答案 2 :(得分:0)
这是一个起点:(例如,您可能希望使用DATEDIFF来计算花费多少时间。
SELECT JobStartTimes.JobNumber ,
JobStartTimes.UserID ,
JobEndTimes.EndTime - JobStartTimes.StartTime AS TimeElapsed
FROM ( SELECT JobNumber ,
UserID ,
MIN(Date) AS StartTime
FROM Jobs
GROUP BY JobNumber ,
UserID
) AS JobStartTimes
INNER JOIN ( SELECT JobNumber ,
UserID ,
MAX(Date) AS EndTime
FROM Jobs
GROUP BY JobNumber ,
UserID
) AS JobEndTimes ON (
JobStartTimes.JobNumber = JobEndTimes.JobNumber
AND JobStartTimes.UserID = JobEndTimes.UserID
)
答案 3 :(得分:0)
如果您使用的是SQLServer 2012或更高版本,并且如果每个任务的持续时间受到日期列的当前值和下一个值的限制,从您的评论看起来似乎是G,那么以下内容将得到您的要求对
WITH schedule AS (
SELECT JobNumber
, UserID
, TaskBegin = Task
, TaskEnd = LEAD([task], 1, [task])
OVER (PARTITION BY jobnumber, userid ORDER BY date)
, DateBegin = [date]
, DateEnd = LEAD([date], 1, [date])
OVER (PARTITION BY jobnumber, userid ORDER BY date)
FROM Jobs)
SELECT UserID
, JobNumber
, Duration
= CAST(DATEADD(ss, SUM(CASE WHEN TaskEnd > TaskBegin
THEN DATEDIFF(ss, DateBegin, DateEnd)
ELSE 0
END), 0) AS Time)
FROM Schedule
GROUP BY JobNumber, UserID
CTE
只是为了让查询更易于阅读,TaskBegin
,TaskEnd
,DateBegin
和DateEnd
的定义可以取代别名在主查询中。
Case
是分割同一UserID
和JobNumber
的作业列表所必需的,作为示例数据中的最后两行。
DATEDIFF
返回一个无法转换为Time
的整数,为此需要进行伪转换,如果结果为秒,则CAST(DATEADD
部分可以被删除< / p>
SQLFiddle演示,该演示有不同的别名
<强>更新强>
由于数据库是SQLServer 2008,因此查询将变得更加复杂
With Tasks As (
SELECT ID
, jobnumber
, userid
, jobdate
, task_num = Replace(Task, 'Task ', '')
, Ord = Row_Number () OVER (PARTITION BY JobNumber, UserID
ORDER BY JobDate)
FROM jobs
)
SELECT t1.UserId
, t1.jobnumber
, Duration
= Cast(DateAdd(ss, Sum(DateDiff(ss, t1.JobDate, t2.JobDate)), 0) as Time)
FROM Tasks t1
INNER JOIN Tasks t2 ON t1.jobnumber = t2.jobnumber
AND t1.userid = t2.userid
AND t1.task_num = t2.task_num - 1
AND t1.Ord = t2.ord - 1
GROUP BY t1.UserId, t1.jobnumber
ORDER BY t1.UserId, t1.jobnumber
SQLFiddle用于SQLServer 2008查询