Sql 如何最好地对2列求和并用sum更新第3列?
我正在寻找在SQLServer表中添加2列或更多列并使用there sum更新另一列的最佳方法 是的,我知道这是一件愚蠢的事情,应该在事务处理时进行计算,但我正在修改一个现有表,其中列中的数据现在需要更详细,但许多进程仍将使用列值 例如,一个列名是TotalDailyMiles,许多进程访问并使用该字段。现在需要更多的细节。需要向表TotalAMMiles和TotalPMMiles中添加两列。这两列将相加为现有列。将访问TotalDailyMiles列的所有进程改为使用2个新列不是一个选项。旧记录中新列的数据不存在,因此包含2个新列之和的列的值不能基于旧记录中的2个新列,因为在旧记录中,新列的值将为0,或者可能为null,但我倾向于0,因此我可以将新列设置为非nullSql 如何最好地对2列求和并用sum更新第3列?,sql,sql-server,Sql,Sql Server,我正在寻找在SQLServer表中添加2列或更多列并使用there sum更新另一列的最佳方法 是的,我知道这是一件愚蠢的事情,应该在事务处理时进行计算,但我正在修改一个现有表,其中列中的数据现在需要更详细,但许多进程仍将使用列值 例如,一个列名是TotalDailyMiles,许多进程访问并使用该字段。现在需要更多的细节。需要向表TotalAMMiles和TotalPMMiles中添加两列。这两列将相加为现有列。将访问TotalDailyMiles列的所有进程改为使用2个新列不是一个选项。旧记
我正在考虑使用触发器根据新列的变化来更新保存总和的列,但我希望你们中的一个聪明人有更好的选择 如何将现有列视为自己的值(在未来的行中将为0),添加两个新列,然后创建一个与旧总计同名的计算列?类似这样的情况(我假设数据类型为
decimal(7,2)
,但当然要使用您拥有的数据类型,尽管我希望它不是float
):
DailyMiles列中可能还需要一些内务管理:
-- if not already NOT NULL
ALTER TABLE dbo.Miles ALTER COLUMN AMMiles decimal(7, 2) NOT NULL;
-- if not already defaulting to 0
ALTER TABLE dbo.Miles ADD
CONSTRAINT DF_Miles_DailyMiles DEFAULT (0) FOR DailyMiles;
您还可以添加一个约束,即DailyMiles
必须为0,或者AMMiles
和PMMiles
都必须为0:
ALTER TABLE dbo.Miles ADD CONSTRAINT CK_Miles_DailyOrAMPM
CHECK (DailyMiles = 0 OR (AMMiles = 0 AND PMMiles = 0));
只要数据的使用者不尝试更新
TotalDailyMiles
列,您就可以轻松地解决问题。触发器无疑是解决问题的方法。我害怕拆分列中有两个零,而总数不匹配。也许至少用值填充一个,用0填充另一个,这样任何新代码都可以工作。@Randy imho,触发器不是好办法。见我的答案。不确定如果添加的列中有一列为空会发生什么。您可能需要编辑计算以使用COALESCE(col,0.0)
这很好。但我还是会带着一个触发器——而且——我会为一些未来的编码人员感到难过,他们看到了所有这些列,并且必须弄清楚在哪一列中插入什么。@Randy——这就是业务规则和文档的意义所在。如果未来的编码人员不知道要插入到哪个列,那么他就不需要处理该表。如果编码人员是如此脆弱,那么仅仅展示您提议的三列内容难道不会让人感到困惑吗?在任何情况下,究竟什么是AMMiles
和PMMiles
的问题必然会出现?在您的场景中,如果事情不同步,并且错误地运行代码UPDATE dbo.Miles SET TotalDailyMiles=totalamiles+totalpmiles
,该怎么办?经过充分考虑后,我仍然建议这样做。@ypercube在我的解决方案中,添加的列被指定为notnull
@ErikE是的,这比你更像是对OP的注释(他多次提到NULL)
ALTER TABLE dbo.Miles ADD CONSTRAINT CK_Miles_DailyOrAMPM
CHECK (DailyMiles = 0 OR (AMMiles = 0 AND PMMiles = 0));