comment faire une boucle à travers une table pour find l'set de données?

Je dois find le timediff en quelques minutes pour une durée de vie de la command. c'est-à-dire que le timeout de command a été reçu (activité ID 1) à key (2) à imprimé (3) à livré (4) pour chaque command

pour par exemple

Je suis complètement perdu à quelle approche devrais-je prendre ?? cas d'utilisation ou si déclaration alors ?? quelque chose comme pour chaque boucle à travers chaque logging? quel devrait être le moyen le plus efficace de le faire?

Je sais une fois que je reçois des dates dans des variables correctes que je peux utiliser 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 

il devrait me montrer @ TurnTime1 = 48 minutes comme orderID 1 a pris 48 minutes de reçu (activité 1) à keyed (activité 2) @ TurnTime2 = 29 minutes comme il a fallu 29 minutes pour l'ordre 1 de keyed (activité 2) à imprimé (Activité ID 3) ainsi de suite et ainsi de suite pour chaque command

Vous pouvez le faire facilement en pivoting datatables. Cela peut être fait de deux façons.

1.Utilisez l' Conditional Aggregate pour faire pivoter datatables. Après avoir datediff vous pouvez find des datediff entre différentes étapes. Essaye ça.

 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.utilisez Pivot pour transposer datatables

 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 

Comme vous l'avez mentionné dans votre question, une façon possible est d'utiliser l'instruction 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 

Au début, je fais une list de toutes les commands ( CTE_Orders ).

Pour chaque command, je reçois quatre dates, une pour chaque ActivityID en utilisant OUTER APPLY . Je suppose que certaines activités pourraient être manquantes (pas encore terminées), donc OUTER APPLY returnnera NULL là. Lorsque je calcule les durées, je suppose que si l'activité ne se trouve pas dans la database, cela ne s'est pas encore produit et je calcule la durée jusqu'à l'heure actuelle. Vous pouvez gérer ce cas différemment si vous avez d'autres besoins.

Je suppose que chaque command peut avoir au plus une ligne pour chaque Activity ID . Si vous pouvez avoir deux ou plusieurs lignes avec le même Order ID et Order ID Activity ID , vous devez décider lequel choisir en ajoutant ORDER BY au SELECT dans l' OUTER APPLY .

 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; 

Ceci le jeu de résultats:

 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 

Vous pouvez facilement calculer d'autres durées, comme le time total de la command (time 4 – time1).

Une fois que vous avez plusieurs requêtes différentes qui produisent le même résultat correct dont vous avez besoin, vous devez mesurer leur performance avec vos données réelles sur votre système pour décider lequel est le plus efficace.

celui-ci devrait remplir vos besoins, mais je suggère d'utiliser cette requête pendant que vous insérez les valeurs dans la table et ajoutez directement cette valeur dans une nouvelle colonne

 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