Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何最好地对2列求和并用sum更新第3列?_Sql_Sql Server - Fatal编程技术网

Sql 如何最好地对2列求和并用sum更新第3列?

Sql 如何最好地对2列求和并用sum更新第3列?,sql,sql-server,Sql,Sql Server,我正在寻找在SQLServer表中添加2列或更多列并使用there sum更新另一列的最佳方法 是的,我知道这是一件愚蠢的事情,应该在事务处理时进行计算,但我正在修改一个现有表,其中列中的数据现在需要更详细,但许多进程仍将使用列值 例如,一个列名是TotalDailyMiles,许多进程访问并使用该字段。现在需要更多的细节。需要向表TotalAMMiles和TotalPMMiles中添加两列。这两列将相加为现有列。将访问TotalDailyMiles列的所有进程改为使用2个新列不是一个选项。旧记

我正在寻找在SQLServer表中添加2列或更多列并使用there sum更新另一列的最佳方法

是的,我知道这是一件愚蠢的事情,应该在事务处理时进行计算,但我正在修改一个现有表,其中列中的数据现在需要更详细,但许多进程仍将使用列值

例如,一个列名是TotalDailyMiles,许多进程访问并使用该字段。现在需要更多的细节。需要向表TotalAMMiles和TotalPMMiles中添加两列。这两列将相加为现有列。将访问TotalDailyMiles列的所有进程改为使用2个新列不是一个选项。旧记录中新列的数据不存在,因此包含2个新列之和的列的值不能基于旧记录中的2个新列,因为在旧记录中,新列的值将为0,或者可能为null,但我倾向于0,因此我可以将新列设置为非null


我正在考虑使用触发器根据新列的变化来更新保存总和的列,但我希望你们中的一个聪明人有更好的选择

如何将现有列视为自己的值(在未来的行中将为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));