SQL Server 2012 - 基于行与行的比较更新列

时间:2013-10-10 19:03:02

标签: sql sql-server compare sql-server-2012 rows

我有一张包含日期和时间的表格。例如,列为DateExTimeNewTimeStatus。我根据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行。

任何有助于弄清楚为什么这种作用而不是所有作品的帮助都会受到赞赏。

广告。

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