我必须在几分钟内找到订单生命周期的timediff。 即从订单收到的时间(活动ID 1)到键盘(2)到打印(3)到交付(4)每个订单
例如
我完全迷失了应该采取哪种方法? 用例还是如果声明?通过每个记录循环的东西? 什么应该是最有效的方法呢?
我知道一旦我得到正确变量的日期,我就可以使用DATEDIFF。
declare @received as Datetime, @keyed as DateTime, @printed as Datetime, @Delivered as Datetime, @TurnTime1 as int
Select
IF (tblOrderActivity.ActivityID = 1) SET @received = tblOrderActivity.ActivityDate
---
----
from tblOrderActivity
where OrderID = 1
它应该显示@ TurnTime1 = 48分钟,因为orderID 1从收到(活动ID 1)到键控(活动ID 2)需要48分钟@TurnTime2 = 29分钟,因为从键控(活动ID 2)开始需要29分钟的订单1 )为每个订单打印(活动ID 3)等等
答案 0 :(得分:4)
您可以通过pivoting
数据轻松完成此操作。可以通过两种方式完成。
1.使用Conditional Aggregate
来转动数据。在pivoting
之后,您可以在不同阶段之间找到datediff
。试试这个。
SELECT orderid,Received,Keyed,Printed,Delivered,
Datediff(minute, Received, Keyed) TurnTime1,
Datediff(minute, Keyed, Printed) TurnTime2,
Datediff(minute, Printed, Delivered) TurnTime3
FROM (SELECT OrderID,
Max(CASE WHEN ActivityID = 1 THEN ActivityDate END) Received,
Max(CASE WHEN ActivityID = 2 THEN ActivityDate END) Keyed,
Max(CASE WHEN ActivityID = 3 THEN ActivityDate END) Printed,
Max(CASE WHEN ActivityID = 4 THEN ActivityDate END) Delivered
FROM Yourtable
GROUP BY OrderID)A
2.使用Pivot
来转置数据
SELECT orderid,
[1] AS Received,
[2] AS Keyed,
[3] AS Printed,
[4] AS Delivered,
Datediff(minute, [1], [2]) TurnTime1,
Datediff(minute, [2], [3]) TurnTime2,
Datediff(minute, [3], [4]) TurnTime3
FROM Yourtable
PIVOT (Max(ActivityDate)
FOR ActivityID IN([1],[2],[3],[4]))piv
答案 1 :(得分:1)
正如您在问题中提到的,一种可能的方法是使用CASE
声明
DECLARE @i INT, @max INT
SELECT @i = MIN(OrderId) FROM tblOrderActivity
SELECT @max = MAX(OrderId) from tblOrderActivity
WHILE @i <= @max
BEGIN
SELECT OrderId
,ActivityID
,ActivityDate
,CASE
WHEN ActivityID = 1 THEN DATEDIFF(MINUTE, ActivityDate, (SELECT ActivityDate FROM C WHERE ActivityID = 2 AND OrderId = @i))
END AS tokeyed
,CASE
WHEN ActivityID = 2 THEN DATEDIFF(MINUTE, ActivityDate, (SELECT ActivityDate FROM C WHERE ActivityID = 3 AND OrderId = @i))
END AS toprinted
,CASE
WHEN ActivityID = 3 THEN DATEDIFF(MINUTE, ActivityDate, (SELECT ActivityDate FROM C WHERE ActivityID = 4 AND OrderId = @i))
END AS todelivered
FROM tblOrderActivity
SET @i = @i + 1
END
答案 2 :(得分:1)
首先,我列出了所有订单(CTE_Orders
)。
对于每个订单,我得到四个日期,每个ActivityID使用OUTER APPLY
一个。我假设某些活动可能会丢失(尚未完成),因此OUTER APPLY
会返回NULL
。当我计算持续时间时,我假设如果活动不在数据库中,它还没有发生,我计算持续时间直到当前时间。如果您有其他要求,可以采用不同的方式处理这种情况。
我假设每个订单每个Activity ID
最多只能有一行。如果您有两行或多行具有相同的Order ID
和Activity ID
,那么您需要通过将ORDER BY
添加到SELECT
内OUTER APPLY
来决定选择哪一行1}}。
DECLARE @TOrders TABLE (OrderID int, ActivityID int, ActivityDate datetime);
INSERT INTO @TOrders (OrderID, ActivityID, ActivityDate) VALUES (1, 1, '2007-04-16T08:34:00');
INSERT INTO @TOrders (OrderID, ActivityID, ActivityDate) VALUES (1, 1, '2007-04-16T08:34:00');
INSERT INTO @TOrders (OrderID, ActivityID, ActivityDate) VALUES (1, 2, '2007-04-16T09:22:00');
INSERT INTO @TOrders (OrderID, ActivityID, ActivityDate) VALUES (1, 3, '2007-04-16T09:51:00');
INSERT INTO @TOrders (OrderID, ActivityID, ActivityDate) VALUES (1, 4, '2007-04-16T16:14:00');
INSERT INTO @TOrders (OrderID, ActivityID, ActivityDate) VALUES (2, 1, '2007-04-16T08:34:00');
INSERT INTO @TOrders (OrderID, ActivityID, ActivityDate) VALUES (3, 1, '2007-04-16T08:34:00');
INSERT INTO @TOrders (OrderID, ActivityID, ActivityDate) VALUES (3, 2, '2007-04-16T09:22:00');
INSERT INTO @TOrders (OrderID, ActivityID, ActivityDate) VALUES (3, 3, '2007-04-16T09:51:00');
INSERT INTO @TOrders (OrderID, ActivityID, ActivityDate) VALUES (3, 4, '2007-04-16T16:14:00');
INSERT INTO @TOrders (OrderID, ActivityID, ActivityDate) VALUES (4, 1, '2007-04-16T08:34:00');
INSERT INTO @TOrders (OrderID, ActivityID, ActivityDate) VALUES (4, 2, '2007-04-16T09:22:00');
INSERT INTO @TOrders (OrderID, ActivityID, ActivityDate) VALUES (4, 3, '2007-04-16T09:51:00');
WITH
CTE_Orders
AS
(
SELECT DISTINCT Orders.OrderID
FROM @TOrders AS Orders
)
SELECT
CTE_Orders.OrderID
,Date1_Received
,Date2_Keyed
,Date3_Printed
,Date4_Delivered
,DATEDIFF(minute, ISNULL(Date1_Received, GETDATE()), ISNULL(Date2_Keyed, GETDATE())) AS Time12
,DATEDIFF(minute, ISNULL(Date2_Keyed, GETDATE()), ISNULL(Date3_Printed, GETDATE())) AS Time23
,DATEDIFF(minute, ISNULL(Date3_Printed, GETDATE()), ISNULL(Date4_Delivered, GETDATE())) AS Time34
FROM
CTE_Orders
OUTER APPLY
(
SELECT TOP(1) Orders.ActivityDate AS Date1_Received
FROM @TOrders AS Orders
WHERE
Orders.OrderID = CTE_Orders.OrderID
AND Orders.ActivityID = 1
) AS OA1_Received
OUTER APPLY
(
SELECT TOP(1) Orders.ActivityDate AS Date2_Keyed
FROM @TOrders AS Orders
WHERE
Orders.OrderID = CTE_Orders.OrderID
AND Orders.ActivityID = 2
) AS OA2_Keyed
OUTER APPLY
(
SELECT TOP(1) Orders.ActivityDate AS Date3_Printed
FROM @TOrders AS Orders
WHERE
Orders.OrderID = CTE_Orders.OrderID
AND Orders.ActivityID = 3
) AS OA3_Printed
OUTER APPLY
(
SELECT TOP(1) Orders.ActivityDate AS Date4_Delivered
FROM @TOrders AS Orders
WHERE
Orders.OrderID = CTE_Orders.OrderID
AND Orders.ActivityID = 4
) AS OA4_Delivered
ORDER BY OrderID;
结果集:
OrderID Date1_Received Date2_Keyed Date3_Printed Date4_Delivered Time12 Time23 Time34
1 2007-04-16 08:34:00.000 2007-04-16 09:22:00.000 2007-04-16 09:51:00.000 2007-04-16 16:14:00.000 48 29 383
2 2007-04-16 08:34:00.000 NULL NULL NULL 4082575 0 0
3 2007-04-16 08:34:00.000 2007-04-16 09:22:00.000 2007-04-16 09:51:00.000 2007-04-16 16:14:00.000 48 29 383
4 2007-04-16 08:34:00.000 2007-04-16 09:22:00.000 2007-04-16 09:51:00.000 NULL 48 29 4082498
您可以轻松计算其他持续时间,例如订单的总时间(时间4 - 时间1)。
一旦你有几个不同的查询产生你需要的正确结果,你应该用你系统上的真实数据来衡量它们的性能,以决定哪个更有效。
答案 3 :(得分:0)
这个应该满足您的需求,但我建议您在将值插入表格时直接将此值添加到新列中时使用此查询
SELECT OrderID,
ActivityID,
ActivityDate,
Datediff(MINUTE, ActivityDate, (SELECT ActivityDate
FROM [TestDB].[dbo].[tblOrderActivity] AS b
WHERE b.OrderID = a.OrderID
AND a.ActivityID + 1 = b.ActivityID))
FROM [TestDB].[dbo].[tblOrderActivity] AS a