简体   繁体   中英

(T-SQL) Sum datetime value gaps based on where clause

Need help writing a query which will sum up time values in date time fields based on another column. Let me explain:

Let's say I have a table Table1 with 2 fields: timeStamp of DATETIME type and player VARCHAR. Let's say I input down a timestamp when playerA got the ball, after some time the playerB got the ball and I input his time, so eventualy I will have something like this:

+-------------------------+---------+
|        TimeLapse        | Player  |
+-------------------------+---------+
| 2017-07-03 10:37:14.740 | playerA |
| 2017-07-03 11:49:14.787 | playerB |
| 2017-07-03 11:53:59.157 | playerA |
| 2017-07-03 12:58:30.313 | playerA |
| 2017-07-03 12:58:34.000 | playerB |
| 2017-07-03 13:58:43.327 | playerA |
| 2017-07-04 19:48:39.817 | playerA |
| 2017-07-05 11:54:53.657 | playerA |
+-------------------------+---------+

What I want in the end is to count the time (let's say in minutes) when the playerA had the ball ( only when he had the ball ). I'm a bit stuck. I have no problems getting all the times playerA had the ball, but then I somehow need to substract the time playerB had the ball. So I need to sum:

time from
 | 2017-07-03 10:37:14.740 | playerA |
to
 | 2017-07-03 11:49:14.787 | playerB |
then from
 | 2017-07-03 11:53:59.157 | playerA |
to
 | 2017-07-03 12:58:30.313 | playerA |
and to
 | 2017-07-03 12:58:34.000 | playerB |
...
and so on

Can someone suggest a strategy, or show how it is done? Thank you.

You can use the difference of row numbers approach to identify the groups. Then you can use aggregation and lead() to get the start and end times, as in the following:

select player, min(timelapse) as start_timelapse, 
       lead(max(timelapse)) over (order by max(timelapse)
                                 ) as next_timelapse
from (select t1.*,
             row_number() over (order by timelapse) as seqnum_t,
             row_number() over (partition by player order by timelapse) as seqnum_tp
      from table1 t1
     ) t1
group by (seqnum_t - seqnum_tp), player;

How this works is a bit tricky. Run the subquery to figure out why the difference of the two row numbers identifies the groups you want.

For the time difference, you want to use the two columns returned. It is unclear what units you want for that, but datediff() would be the typical method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM