SQL Server 2012 – mise à jour d'une colonne basée sur la comparaison de ligne à ligne

J'ai une table qui contient des dates et des heures. Par exemple, les colonnes sont Date , ExTime , NewTime , Status . Je les command en fonction d'une colonne expkey qui les fait apparaître dans le bon ordre.

Je veux faire une comparaison rangée par ligne et comparer la colonne de deuxième ligne de extime à la colonne de première ligne NewTime . Si extime <Newtime alors je veux mettre à jour le status avec un "1". Puis traversez la table rangée par rangée où la deuxième rangée dans l'exemple ci-dessus devient la première et une nouvelle seconde est tirée et utilisée. Voici un échantillon de ce que j'ai maintenant – mais il ne frappe pas et ne fonctionne pas toutes les lignes pour une raison quelconque.

 UPDATE t SET t.Status = 1 FROM MyTable t CROSS APPLY (SELECT TOP 1 NewTime FROM MyTable WHERE ID = t.ID AND [Date] = t.[Date] ORDER BY ExpKey) t1 WHERE t.Extime < t1.NewTime 

Cela ne frappe pas toutes les lignes comme je le veux. J'ai la clause where comparant les champs ID et Date pour s'assurer que les lignes sont attachées à la même personne. Si l'ID ou les dates ne sont pas les mêmes, il n'est pas attaché à la même personne, donc je ne voudrais pas mettre à jour le statut. Donc, fondamentalement, si l'ID de la ligne 2 = ID de la ligne 1 et Date de la ligne 2 = Date de la ligne 1, je veux comparer extime de la ligne 2 et voir si elle est inférieure à la nouvelle ligne de la ligne 1 de la rangée 2.

Toute aide pour comprendre pourquoi ce genre de travaux mais pas sur tout serait apprécié.

Un d.

Sur SQL Server 2012, vous pouvez facilement mettre à jour l' status avec la fonction window lag() :

 with cte as ( select extime, lag(newtime) over(partition by id, date order by expKey) as newtime, status from table1 ) update cte set status = 1 where extime < newtime; 

sql fiddle démo

Je n'ai pas testé cela, mais j'ai traité des problèmes similaires de comparaison de lignes adjacentes. Je mets ça set, donc il faudra peut-être le peaufiner, mais essayez-le.

 ;WITH CTE AS ( SELECT ID,[Date],ExpKey,ExTime,NewTime, ROW_NUMBER()OVER(PARTITION BY ID,[Date] ORDER BY ExpKey) AS Sort FROM MyTable ) UPDATE row2 SET row2.[Status] = 2 WHERE row2.ExTime < row1.NewTime FROM CTE row2 CROSS JOIN CTE row1 ON row1.ID = row2.ID AND row1.[Date] = row2.[Date] AND row1.Sort = row2.Sort-1 --Join to prior row