In the table below, there are job activities and unique identifiers under lodnum. I’m trying to figure out a way to get the time difference in between a job. A job such as pallet move has two entries. As you can see in rows 1 and 2, that is a pallet move for pallet A. Imagine the first entry as picking up the pallet, and the second entry as setting it down. Rows 3 and 4 are a separate job that are moving the pallet somewhere else. Rows 7 and 9 are a different job as well, sometimes thet skip a few rows. I’d like to figure out the time it takes each user to perform each job. As well as the time in between each job for a user.
How could I do this in SQL or Power BI?
+---------+-----------------+--------+------+-------+-----+---------+--------+-------+
| Row Num | activity | usr_id | year | month | day | time | lodnum | wh_id |
+---------+-----------------+--------+------+-------+-----+---------+--------+-------+
| 1 | Pallet Move | User1 | 2020 | 8 | 5 | 8:24:23 | A | WH1 |
| 2 | Pallet Move | User1 | 2020 | 8 | 5 | 8:24:30 | A | WH1 |
| 3 | Pallet Move | User2 | 2020 | 8 | 5 | 8:25:10 | A | WH1 |
| 4 | Pallet Move | User2 | 2020 | 8 | 5 | 8:25:14 | A | WH1 |
| 5 | Pallet Move | User1 | 2020 | 8 | 5 | 8:25:27 | B | WH1 |
| 6 | Pallet Move | User1 | 2020 | 8 | 5 | 8:25:30 | B | WH1 |
| 7 | Inbound Putaway | User3 | 2020 | 8 | 6 | 4:19:58 | C | WH2 |
| 8 | Inbound Putaway | User3 | 2020 | 8 | 6 | 4:19:59 | D | WH2 |
| 9 | Inbound Putaway | User3 | 2020 | 8 | 6 | 4:22:05 | C | WH2 |
| 10 | Inbound Putaway | User3 | 2020 | 8 | 6 | 4:22:10 | D | WH2 |
| 11 | Trailer Load | User1 | 2020 | 8 | 6 | 6:22:17 | E | WH3 |
| 12 | Trailer Load | User1 | 2020 | 8 | 6 | 6:22:23 | F | WH3 |
| 13 | Trailer Load | User1 | 2020 | 8 | 6 | 6:22:26 | E | WH3 |
| 14 | Trailer Load | User1 | 2020 | 8 | 6 | 6:22:30 | F | WH3 |
+---------+-----------------+--------+------+-------+-----+---------+--------+-------+
Advertisement
Answer
Some assumptions:
- Job start and ends always on the same day? Important for the caculation.
- Unique combination of activity / usr_id / year / month / lodnum / wh_id defines ‘one’ job
Please let us know if this is correct?
Possible solution:
First, I built a CTE (Common Table Expression) which adds two columns:
- [Row] time column defining the order of the jobs, based on the combination of unique columns. Results in 1 and 2: start job and end job.
- [Key] creating a key based on combination of unique columns, for the join later.
Second, I join two versions of the CTE: one with the filter on [Row] = 1 (start job) which joins the second one on [Key] and [Row] = 2. Then caculates the difference in seconds.
WITH CTE AS (
SELECT
[activity]
,[usr_id]
,[year]
,[month]
,[day]
,[time]
,[lodnum]
,[wh_id]
,ROW_NUMBER() OVER (PARTITION BY activity, usr_id, year, month, day, lodnum, wh_id ORDER BY [time]) as [Row]
,RANK() OVER (ORDER BY activity, usr_id, year, month, day, lodnum, wh_id) as [Key]
FROM [dbo].[JobActivities] )
SELECT
StartTime.usr_id,
StartTime.activity,
StartTime.day,
StartTime.time as [Start Time],
EndTime.time as [End Time],
DATEDIFF(SECOND, StartTime.time, EndTime.time) as [Difference (s)]
FROM
CTE StartTime
LEFT OUTER JOIN CTE EndTime ON StartTime.[Key] = EndTime.[Key] AND EndTime.Row = 2
WHERE StartTime.Row = 1
ORDER BY StartTime.day, StartTime.time
Solution 2 – Using LEAD (without join, better performance):
WITH CTE AS (
SELECT [Row Num]
,[activity]
,[usr_id]
,[year]
,[month]
,[day]
,[time] [Start Time]
,[lodnum]
,[wh_id]
,ROW_NUMBER() OVER (PARTITION BY activity, usr_id, year, month, day, lodnum, wh_id ORDER BY [time]) as [Row]
,LEAD([time]) OVER (PARTITION BY activity, usr_id, year, month, day, lodnum, wh_id ORDER BY [time]) AS [End Time]
FROM [dbo].[JobActivities] )
SELECT
usr_id,
activity,
day,
[Start Time],
[End Time],
DATEDIFF(SECOND, [Start Time], [End Time]) as [Difference (s)]
FROM
CTE
WHERE Row = 1
ORDER BY day, [Start Time]