如何通过 table 循环查找数据集?
how to loop thru a table to find data set?
我必须找到订单生命周期的时差(以分钟为单位)。
即每个订单从收到订单(Activity ID 1)到输入(2)到打印(3)到交付(4)的时间
例如
我完全不知道我应该采用哪种方法??
用例或 if then 语句 ??每个循环遍历每条记录之类的东西?
最有效的方法应该是什么?
我知道一旦我在正确的变量中获得日期,我就可以使用 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 从收到(activity id 1)到键入(activity id 2)需要 48 分钟@TurnTime2 = 29 分钟订单 1 从键控(activity id 2)到打印(activity id 3)需要 29 分钟,依此类推每个订单
正如您在问题中提到的,一种可能的方法是使用 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
这个应该可以满足您的需求,但我建议您在将值插入 table 并直接将此值添加到新列中时使用此查询
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
首先我列出了所有订单 (CTE_Orders
)。
对于每个订单,我得到四个日期,每个 ActivityID 使用 OUTER APPLY
。我假设某些活动可能会丢失(尚未完成),所以 OUTER APPLY
会 return NULL
在那里。当我计算持续时间时,我假设如果 activity 不在数据库中,它还没有发生,我计算持续时间到当前时间。如果您有其他需求,可以另行处理。
我假设每个订单最多只能有一行 Activity ID
。如果您可以有两行或更多行具有相同的 Order ID
和 Activity ID
,那么您需要通过将 ORDER BY
添加到 SELECT
内的 [=] 来决定选择哪一行13=].
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)。
一旦你有几个不同的查询产生了你需要的相同的正确结果,你应该用你系统上的真实数据来衡量它们的性能,以确定哪个更有效。
您可以通过 pivoting
轻松完成此操作 data.It 可以通过两种方式完成。
1.Use 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.use 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
我必须找到订单生命周期的时差(以分钟为单位)。 即每个订单从收到订单(Activity ID 1)到输入(2)到打印(3)到交付(4)的时间
例如
我完全不知道我应该采用哪种方法?? 用例或 if then 语句 ??每个循环遍历每条记录之类的东西? 最有效的方法应该是什么?
我知道一旦我在正确的变量中获得日期,我就可以使用 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 从收到(activity id 1)到键入(activity id 2)需要 48 分钟@TurnTime2 = 29 分钟订单 1 从键控(activity id 2)到打印(activity id 3)需要 29 分钟,依此类推每个订单
正如您在问题中提到的,一种可能的方法是使用 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
这个应该可以满足您的需求,但我建议您在将值插入 table 并直接将此值添加到新列中时使用此查询
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
首先我列出了所有订单 (CTE_Orders
)。
对于每个订单,我得到四个日期,每个 ActivityID 使用 OUTER APPLY
。我假设某些活动可能会丢失(尚未完成),所以 OUTER APPLY
会 return NULL
在那里。当我计算持续时间时,我假设如果 activity 不在数据库中,它还没有发生,我计算持续时间到当前时间。如果您有其他需求,可以另行处理。
我假设每个订单最多只能有一行 Activity ID
。如果您可以有两行或更多行具有相同的 Order ID
和 Activity ID
,那么您需要通过将 ORDER BY
添加到 SELECT
内的 [=] 来决定选择哪一行13=].
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)。
一旦你有几个不同的查询产生了你需要的相同的正确结果,你应该用你系统上的真实数据来衡量它们的性能,以确定哪个更有效。
您可以通过 pivoting
轻松完成此操作 data.It 可以通过两种方式完成。
1.Use 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.use 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