在条件更新语句中使用SUM

时间:2010-07-08 19:09:50

标签: sql sql-update set-based

我一直试图搜索这个,但我不确定我是否使用了正确的术语。或者可能只是因为它不可能。但我要做的是更新表中构成小于设定值的总和值的所有记录。

所以这是一个例子:

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的记录。所以当我这样做时,总和id 1和2将等于20,小于22.但它也需要仅对processed_date具有null的记录。我也想让它工作,以便从最旧到最新更新。

基本上我会用伪代码编写它:

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

但我知道这不起作用。所以我希望一些SQL大师可能有想法。

我确定我可以在游标中写这个但是我想知道是否有基于集合的方式来执行此操作。

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

2 个答案:

答案 0 :(得分:2)

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_INSERT将“稍后”行插入这些间隙。相反,您应该使用datetime列。如果该列为received_date,则只需在上述查询中将Id替换为received_date

答案 1 :(得分:1)

您应该在此类情况下使用HAVING子句。

根据w3schools,“HAVING子句已添加到SQL中,因为WHERE关键字不能与聚合函数一起使用。”

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

这是w3schools上发现的一个很棒的教程

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