【问题标题】:sql update table from different columns of another tablesql从另一个表的不同列更新表
【发布时间】:2010-11-14 09:17:01
【问题描述】:

我有 2 张桌子:

表1

S/N  OnId    FromDate      ToDate      Value  
aaa   1     2010-10-09    2010-10-15     ?  
aaa   2     2010-10-10    2010-10-29     ?  
bbb   1     2010-10-16    2010-10-20     ?  

表2

Id     Date          Count  
1     2010-10-03     100  
2     2010-10-03     150  
1     2010-10-08     200  
2     2010-10-12     250  
1     2010-10-13     300  
1     2010-10-14     400  
2     2010-10-17     450  
1     2010-10-20     500  

我需要从 Table2 中找到具有相同 Id 和小于 FromDate 的日期(称为“FromCount”)的最新计数,以及具有相同 Id 和小于 ToDate 的日期的最新计数(称为“ ToCount'),并用它们的差异更新 Table1 中的 Value 列。所以中间计算应该是这样的:

S/N  OnId    FromDate      ToDate      FromCount  ToCount
aaa   1     2010-10-09    2010-10-15      200       400   
aaa   2     2010-10-10    2010-10-29      150       450  
bbb   1     2010-10-16    2010-10-20      400       500    

在 UPDATE 之后,Table1 将如下所示:

表1

S/N  OnId    FromDate      ToDate      Value  
aaa   1     2010-10-09    2010-10-15     200 (400-200)   
aaa   2     2010-10-10    2010-10-29     300 (450-150)  
bbb   1     2010-10-16    2010-10-20     100 (500-400)    

之后我需要汇总相同 S/N 的所有值:

表3

S/N    Total
aaa     500
bbb     100

我用的是sql server 2005,希望用sql成功,不需要全部写 这在我的 C# 应用程序中 :)

谢谢!!!

【问题讨论】:

  • Leon,您是卡在某个特定步骤上,还是需要帮助开始,还是想要整个解决方案?
  • 真的不太清楚在哪种情况下要选择哪些行.....你能详细说明一下吗?对于 S/N=aaaOnId=1 - 您选择表 2 中的哪两行,为什么选择这两行??
  • 对于 S/N=aaa 和 OnId=1 第 6 行和第 3 行。我需要计算 FromDate 和 ToDate 之间的计数差。对于 2010-10-15,最新计数来自 2010-10-14(第 6 行),对于 2010-10-09,最新计数来自 2010-10-8(第 3 行)。我知道如何使用 SELECT (TOP 1)...WHERE (date>=FromDate) ORDER BY DATE DESC 获取最新计数,但我不知道如何为 FromDate 和 ToDate 进行计算

标签: sql


【解决方案1】:

你需要两个correlated subqueries:

这是一个带有一个子查询的查询:

SELECT t1.SN, t1.OnId, t1.FromDate, t1.ToDate,
      (SELECT TOP 1 Count
       FROM table2 t2To
       WHERE t2To.Id = t1.OnId AND t2To.Date <= t1.ToDate
       ORDER BY t2To.Date DESC)
FROM table1 t1

这给了你这个:

aaa         1   2010-10-09    2010-10-15    400  
aaa         2   2010-10-10    2010-10-29    450  
bbb         1   2010-10-16    2010-10-20    500  

你需要添加另一个,然后把它变成一个UPDATE查询:

UPDATE table1
SET Value = 
   (SELECT ...) - (SELECT ...)

【讨论】:

  • 这并不能完全回答这个问题,因为需要两个 count 实例(一个用于“from”,一个用于“to”),但它肯定朝着正确的方向前进
  • 这看起来很难看。更新中的子查询中的子查询?在这种情况下,我的教授曾经说过“如果你已经达到了 3 的深度,那么你肯定做错了什么,或者这是在地狱般的数据库中进行的地狱般的查询”。这看起来不像是一个地狱般的数据库。我稍后会分析这个(现在没有时间)。如果我不能想出更好的东西,那我就错了:)。
  • @Murph:不,我知道 - 我有一个完整的解决方案,但我认为最好在正确的方向上提供帮助。给男人一条鱼,等等……
  • @Alexander:它不是嵌套到三层,而是“嵌套”到一层:UPDATE ... SET Value = - 诚然有两个子查询,但它们是只有在那里计算两个值;它们没有嵌套。
  • @Alexander:这并不是说没有比子查询更好的方法,只是我的方法不使用嵌套子查询。
【解决方案2】:

这行得通:

 UPDATE table1  
 SET Value =   
 (
    isnull( 
       (SELECT TOP 1 Count 
        FROM table2 t2To 
        WHERE t2To.Id = t1.OnId AND t2To.Date <= t1.ToDate 
        ORDER BY t2To.Date DESC) 
    ,0.0)
 )-(
    isnull(
       (SELECT TOP 1 Count 
        FROM table2 t2To 
        WHERE t2To.Id = t1.OnId AND t2To.Date <= t1.FromDate 
        ORDER BY t2To.Date DESC) 
    ,0.0)
 )

谢谢!

【讨论】:

  • 使用 isnull(test_value, what_if_null_value) 或 coalesce(test_value1, test_value2, test_value3 ..... test_valueN)。如果可行,请接受答案。
  • 谢谢!你能告诉我如何在 sql server 2005 的查询窗口中查看声明变量的值吗?
猜你喜欢
  • 2011-04-18
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 2021-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多