我有一张包含日期和时间的表格。例如,列为Date
,ExTime
,NewTime
,Status
。我根据expkey
列对它们进行排序,使它们以正确的顺序显示。
我想逐行比较并将extime
的第二行列与第一行NewTime
进行比较。如果extime< Newtime然后我想用“1”更新status
。然后逐行遍历表格,上面例子中的第二行成为第一行,新的第二行是拉取和使用。以下是我现在所拥有的一个示例 - 但由于某种原因,它并没有击中并处理所有行。
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
这并没有像我想要的那样击中所有行。我有where子句比较字段ID和日期以确保行附加到同一个人。如果ID或日期不同,则它不会附加到同一个人,因此我不想更新状态。所以基本上如果第2行的ID =第1行的ID和第2行的日期=第1行的日期我想比较第2行的extime并查看它是否小于第1行的新时间 - 如果是,则更新状态字段第2行。
任何有助于弄清楚为什么这种作用而不是所有作品的帮助都会受到赞赏。
广告。
答案 0 :(得分:4)
在SQL Server 2012上,您可以使用窗口函数lag()
轻松更新status
:
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 demo 强>
答案 1 :(得分:0)
我没有对此进行测试,但我已经处理了比较相邻行的类似问题。我把它放在袖口,所以它可能需要调整,但试一试。
;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