【问题标题】:SQL Server 2012 Update table rate based on rate in table 2SQL Server 2012 根据表 2 中的速率更新表速率
【发布时间】:2017-07-24 05:03:27
【问题描述】:

我有两张表,下面是例子

Table1
KEY     BEGIN_DATE         TOTAL_RATE    
1       1974-01-01        3    
1       1981-01-01        3    
1       1983-01-01        4    
1       1985-07-01        4        
1       1989-10-01        7    
1       1990-07-01        10    
1       1997-10-01        11    
1       2008-04-01        13    

表2

KEY     END_DATE          RATE_REDUCED    
1       1989-09-30       2    
1       1997-09-31       4    

如果键匹配,则从表 2 中我们需要从表 1 中减少 TOTALRATE 在表 2 中使用 RATEREDUCED,其中 BEGINDATE > ENDDATE 并且应该发生 直到表 2 ENDDATE 结束

预期结果/表 1 更新:
结果

KEY     BEGIN_DATE        NEW_RATE    
1       1974-01-01       3    
1       1981-01-01       3    
1       1983-01-01       4    
1       1985-07-01       4    
1       1989-10-01       7  - 2      = 5 (Date is Greater than 1989-09-30)     
1       1990-07-01       10 - 2      = 8 (Date is Greater than 1989-09-30)    
1       1997-10-01       11 - 2 - 4  = 5 (Date is Greater than two dates)    
1       2008-04-01       13 - 2 - 4  = 7 (Date is Greater than two dates)    

我在表二和表一中有很多键。 是否可以加入更新

提前致谢

【问题讨论】:

    标签: sql sql-server sql-server-2012 sql-update outer-join


    【解决方案1】:

    与 Gordon 的类似,这里我们在 CROSS APPLY 中使用更新。这种方法只会更新符合条件的记录

    Update Table1 Set TOTAL_RATE=TOTAL_Rate-B.Adj
     From  Table1 A
     Cross Apply (
                  Select Adj=sum(RATE_REDUCED) 
                   From  Table2 
                   Where END_DATE<=A.BEGIN_DATE and [Key]=A.[Key] 
                  ) B
     Where B.Adj is not NULL
    

    更新后的 Table1 现在看起来像这样

    KEY BEGIN_DATE  TOTAL_RATE
    1   1974-01-01  3
    1   1981-01-01  3
    1   1983-01-01  4
    1   1985-07-01  4
    1   1989-10-01  5
    1   1990-07-01  8
    1   1997-10-01  5
    1   2008-04-01  7
    

    【讨论】:

      【解决方案2】:

      这看起来像是outer apply 的一个很好的应用程序:

      select t1.*,
             (t1.total_rate - coalesce(t2.rate_reduced, 0)) as total_rate
      from table1 t1 outer apply
           (select sum(t2.rate_reduced) as rate_reduced
            from table2 t2
            where t1.begin_date > t2.end_date and
                  t1.key = t2.key
           ) t2;
      

      编辑:

      如果你想把它变成update,那很简单:

      update t1 
          set total_rate = (t1.total_rate - coalesce(t2.rate_reduced, 0)) 
      from table1 t1 outer apply
           (select sum(t2.rate_reduced) as rate_reduced
            from table2 t2
            where t1.begin_date > t2.end_date and
                  t1.key = t2.key
           ) t2;
      

      【讨论】:

      • @StephanLechner 。 . .我更关注问题的“预期结果”而不是“更新”部分。
      【解决方案3】:

      我不确定使用联接或使用子查询之间的性能差异。也许您可以尝试其他答案中提到的解决方案并将其与(更简单的?)子查询方法进行比较:

      update table1
      set total_rate = total_rate - 
          (select COALESCE(sum(new_rate),0)
           from table2
           where begin_date > end_date
             and table1.key = table2.key)
      

      【讨论】:

      • 谢谢 Stephan,这行得通,我看不出性能有任何差异
      猜你喜欢
      • 2010-12-17
      • 2019-08-05
      • 1970-01-01
      • 2021-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-03
      • 1970-01-01
      相关资源
      最近更新 更多