代码之家  ›  专栏  ›  技术社区  ›  spinon

在update语句中使用SUM

  •  2
  • spinon  · 技术社区  · 14 年前

    我一直在试图寻找这个,不确定我用的是正确的术语。或者只是不可能。但是我要做的是更新一个表中的所有记录,这些记录构成了一个小于设定值的和值。

    下面是一个例子:

    ID   type    amount   received_date    processed_date
    1    debit   10       7/1/2010         NULL
    2    debit   10       7/2/2010         NULL
    3    debit   10       7/3/2010         NULL
    

    现在我要做的是更新所有小于22的记录。所以当我做的时候,1和2的和等于20,小于22。但它也必须是只有处理日期为空的记录。我还想让它工作,使它从最旧的更新到最新的。

    UPDATE credits
    SET date_processed = '8/1/2010'
    WHERE SUM(amount) <= @total AND
        credit_type = [debits]
    

    我确信我可以在一个游标中写这个,但是我想知道是否有一个基于集合的方法来执行这个。

    编辑: 我更新了下表和简要说明,以便更好地描述我的情况。

    2 回复  |  直到 12 年前
        1
  •  2
  •   Thomas    14 年前

    SQL表中的行表示无序的项列表。因此,我们必须提供订单。在您的示例中,您提示它应该处理按Id排序的行。

    Update TableName
    Set processed_date = '2010-08-01'
    Where [type] = 'debit'
        And Exists      (
                        Select 1
                        From TableName As C1
                        Where C1.Id <= TableName.Id
                            And C1.[type] = 'debit'
                        Having Sum(C1.amount) <= @total
                        )
    

    正如我在评论中提到的,依赖Id作为序列的标记是不安全的。有可能存在间隙,并且有人可以使用IDENTITY\u insert将“稍后”行插入这些间隙。相反,应该使用datetime列。如果那列是 received_date ,然后简单地替换 Id 对于 在上面的查询中。

        2
  •  1
  •   Ranhiru Jude Cooray    14 年前

    对于这种情况,应该使用HAVING子句。

    UPDATE credits
    SET date_processed = '8/1/2010'
    WHERE credit_type = [debits]
    HAVING SUM(amount) <= @total 
    

    这里有一个关于学校的很棒的教程

    http://www.w3schools.com/SQL/sql_having.asp