SQL Query总结了一个数据表

时间:2014-05-06 12:32:16

标签: sql sql-server sql-server-2008 tsql

我的表中包含以下数据:

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然后减去该组的最大和最小日期,但不太确定我是如何做到的。

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:1)

你不必在这里使用行号。只需使用分组

select userid, jobnumber, cast(max(date)-min(date) as time)
from table1
group by userid, jobnumber
order by userid

Fiddle

答案 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只是为了让查询更易于阅读,TaskBeginTaskEndDateBeginDateEnd的定义可以取代别名在主查询中。 Case是分割同一UserIDJobNumber的作业列表所必需的,作为示例数据中的最后两行。
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查询