I have a status table the contains an orderNO, Insert_Date, and status. My goal is to determine the time duration between status changes. The issue is that if whoever is entering the order clicks the status change buttons multiple times, I'll have multiple instances of each status. I pulled an example of a particular orderNO below:
+------------+---------+--------------------------+
| orderNO | status | insert_date |
+------------+---------+--------------------------+
| OBJV107522 | ENTERED | 2/4/2019 11:44:45.800 AM |
| OBJV107522 | ENTERED | 2/4/2019 11:45:14.410 AM |
| OBJV107522 | ENTERED | 2/4/2019 11:45:14.597 AM |
| OBJV107522 | ENTERED | 2/4/2019 11:45:14.833 AM |
| OBJV107522 | OPEN | 2/4/2019 12:27:15.710 PM |
| OBJV107522 | ENTERED | 2/4/2019 12:36:39.327 PM |
| OBJV107522 | ENTERED | 2/4/2019 12:36:39.920 PM |
| OBJV107522 | OPEN | 2/4/2019 2:34:58.957 PM |
| OBJV107522 | ENTERED | 2/4/2019 2:35:07.817 PM |
| OBJV107522 | OPEN | 2/4/2019 3:50:04.393 PM |
+------------+---------+--------------------------+
I would ideally like to see the minutes elapsed between a status change. The output would need to look like this.
+------------+------------+-----------------+
| orderNO | New_status | minutes_elapsed |
+------------+------------+-----------------+
| OBJV107522 | OPEN | 42 | 4th row - 5th row of the original data
| OBJV107522 | ENTERED | 9 | 5th row-7th row of the original data
| OBJV107522 | OPEN | 118 |
| OBJV107522 | ENTERED | 0 |
| OBJV107522 | OPEN | 75 |
+------------+------------+-----------------+
I'm getting no where trying this on my own. I'm starting to convince myself it's not possible. Please let me know of any suggestions.
Maybe something like this to take advantage of windowing functions.
WITH CTE AS(
SELECT *,
LAG( status) OVER( PARTITION BY orderNO ORDER BY insert_date) AS Previous_Status,
LAG( insert_date) OVER( PARTITION BY orderNO ORDER BY insert_date) AS Previous_Date
FROM OrderStatus
)
SELECT orderNO,
status,
DATEDIFF(mi, Previous_Date, insert_date) AS minutes_elapsed,
ROUND(DATEDIFF(ss, Previous_Date, insert_date)/60., 0) AS minutes_elapsed2 /*This actually matches your expected results*/
FROM CTE
WHERE status <> Previous_Status;
DECLARE @t TABLE (orderNO VARCHAR(20),status VARCHAR(20), insert_date DATETIME)
INSERT INTO @t VALUES
(' OBJV107522 ',' ENTERED ',' 2/4/2019 11:44:45.800 AM '),
(' OBJV107522 ',' ENTERED ',' 2/4/2019 11:45:14.410 AM '),
(' OBJV107522 ',' ENTERED ',' 2/4/2019 11:45:14.597 AM '),
(' OBJV107522 ',' ENTERED ',' 2/4/2019 11:45:14.833 AM '),
(' OBJV107522 ',' OPEN ',' 2/4/2019 12:27:15.710 PM '),
(' OBJV107522 ',' ENTERED ',' 2/4/2019 12:36:39.327 PM '),
(' OBJV107522 ',' ENTERED ',' 2/4/2019 12:36:39.920 PM '),
(' OBJV107522 ',' OPEN ',' 2/4/2019 2:34:58.957 PM '),
(' OBJV107522 ',' ENTERED ',' 2/4/2019 2:35:07.817 PM '),
(' OBJV107522 ',' OPEN ',' 2/4/2019 3:50:04.393 PM ');
SELECT t2.orderNO, t2.status, t2.insert_date
, minutes_elapsed = MAX(DATEDIFF(SECOND, t.insert_date, t2.insert_date)/60)
FROM @t as t
CROSS APPLY (
SELECT insert_date = MIN(t1.insert_date)
FROM @t as t1
WHERE t1.status != t.status
and t1.insert_date > t.insert_date
) as tm
INNER JOIN @t as t2 ON t2.insert_date = tm.insert_date
GROUP BY t2.orderNO, t2.status, t2.insert_date
ORDER BY t2.insert_date
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.