【问题标题】:t sql increment date column value based on previous row date valuet sql 根据前一行日期值递增日期列值
【发布时间】:2021-04-03 01:55:31
【问题描述】:

我在#Temp1 表中有如下数据列:(Unit asc,dateTime asc 的表上有一个现有的聚集索引)

rowID unit   dateTime          newUnit  dateDiff
  1    A    2018-06-01 04:10      1       0
  2    A    2018-06-01 04:12      0       2
  3    A    2018-06-01 04:15      0       3
  4    A    2018-06-01 04:15      0       0
  5    A    2018-06-01 04:16      0       1
  6    A    2018-06-01 04:17      0       1
  7    B    2018-06-22 23:12      1       -305
  8    B    2018-06-01 23:14      0       2
  9    B    2018-06-01 23:18      0       4
 10    B    2018-05-22 23:18      0       0
 11    B    2018-06-01 23:22      0       4
 12    B    2018-06-01 23:31      0       9

忽略第一行,当 dateDiff 为 0 时,我想在前一行值上将 dateTime 增加 2 分钟。如果一个新的 dateTime 增加的值意味着它现在等于或大于之后下一行中的 dateTime,它应该增加下一个 datetime 并继续这样做,直到差异大于 0。该过程应该重新启动是单位的变化(newUnit = 1)。 dateDiff 不需要使用新的差异进行更新。

接下来我想根据 rowID 使用来自 #Temp1 的新 dateTime 值更新另一个表 #Temp2,该表当前保存旧的 dateTime 值。

经过对 S.O. 的一些研究。我认为类似以下的方法可能有效,但我没有 SQL 知识来破解它!

  WHILE (SELECT COUNT(*) FROM #Temp1) > 0
        BEGIN
        UPDATE TOP (1) #Temp2  
        SET [dateTime] = DATEADD(minute, 2, #Temp1.[dateTime])
        FROM #Temp1
        WHERE #Temp2.moveID = #Temp1.moveID + 1  
           .... plus other conditions to update [dateTime]
    END

非常感谢任何有关破解此问题的帮助。

【问题讨论】:

    标签: sql tsql sql-server-2012


    【解决方案1】:

    您可以使用窗口函数和可更新的 CTE:

    with toupdate as (
          select t.*,
                 row_number() over (partition by unit order by datetime) as seqnum,
                 min(datetime) over (partition by unit) as min_datetime
          from #temp1 t
         )
    update toupdate
        set datetime = dateadd(minute, 2 * seqnum - 2, min_datetime)
        where seqnum > 1;
    

    这会计算每个unit 的序号。然后它使用算术来设置每一行中的datetime 值。

    【讨论】:

    • 是的,您的解决方案效果很好,谢谢。我还对其进行了修改,以使用每个分区上 dateDiff 的平均值,而不仅仅是 2 的增量。为了获得更好的精度,您还可以帮助我将 dateDiff 平均值计算的结果转换为小数点到小数点后 1 位吗? dateDiff 值是用以下公式计算的: CAST(DATEDIFF(MINUTE,t1.dateTime, t2.dateTime)as decimal (10,2)) as dateDiff 但是当在 cte 中使用 dateDiff 时,它似乎被自动分配的数据类型覆盖由 cte??
    • @FyllSee 。 . . DATEDIFF() 返回一个整数。也许你应该用样本数据和期望的结果问另一个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    相关资源
    最近更新 更多