我有一个状态表,其中包含orderNO,Insert_Date和状态。我的目标是确定状态更改之间的时间间隔。问题是,如果输入订单的任何人多次单击状态更改按钮,我将获得每个状态的多个实例。我在下面拉了一个特定orderNO的示例:
+------------+---------+--------------------------+
| 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 |
+------------+---------+--------------------------+
理想情况下,我希望看到状态更改之间经过的分钟数。输出将需要像这样。
下一行应该是第一个“ OPEN”实例的最大值(在状态更改回“ ENTERED”之前,减去第二个“ ENTERED”的最大值)。
+------------+------------+-----------------+
| 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 |
+------------+------------+-----------------+
我无法独自尝试。我开始说服自己这是不可能的。请让我知道任何建议。
答案 0 :(得分:2)
也许这样的事情可以利用窗口功能。
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;
答案 1 :(得分:0)
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