【问题标题】:SQL Server 2012 - updating a column based on row to row comparisonSQL Server 2012 - 根据行间比较更新列
【发布时间】:2013-10-10 19:03:02
【问题描述】:

我有一个包含日期和时间的表格。例如列是DateExTimeNewTimeStatus。我根据expkey 列对它们进行排序,使它们以正确的顺序显示。

我想进行逐行比较,并将extime 的第二行列与第一行列NewTime 进行比较。如果 extime 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

这并没有像我想要的那样击中所有行。我有比较字段 ID 和日期的 where 子句,以确保这些行附加到同一个人。如果 ID 或 Dates 不同,则它不会附加到同一个人,所以我不想更新状态。所以基本上如果第 2 行的 ID = 第 1 行的 ID 和第 2 行的日期 = 第 1 行的日期我想比较第 2 行的 extime 并查看它是否小于第 1 行的 newtime - 如果是,则更新状态字段第 2 行。

任何帮助弄清楚为什么这种工作但不是全部都将不胜感激。

广告。

【问题讨论】:

  • 我认为你不能在纯 SQL 中做到这一点。您需要某种程序来执行此操作。
  • @Andrew 如果我正确理解问题,这可以通过 SQL 2012 中的滞后函数或 SQL Server 2008 中的 apply 或 row_number 更笨拙的解决方案来实现

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


【解决方案1】:

在 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

【讨论】:

    【解决方案2】:

    我没有对此进行测试,但我已经处理过比较相邻行的类似问题。我是现成的,所以它可能需要调整,但试一试。

    ;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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-27
      • 2017-06-20
      • 2017-04-16
      • 2015-06-04
      • 1970-01-01
      • 2019-04-16
      • 2016-11-17
      • 1970-01-01
      相关资源
      最近更新 更多