如何最好地总结2列并用sum更新第3列?

时间:2014-01-10 02:21:31

标签: sql sql-server

我正在寻找在SQL Server表中添加2个或更多列的最佳方法,并使用sum更新另一列。

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

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

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

1 个答案:

答案 0 :(得分:3)

如何将现有列视为自己的值(在将来的行中为0),添加两个新列,然后创建一个与旧Total相同名称的计算列?这样的事情(我假设数据类型为decimal(7, 2),但当然使用你拥有的,但我希望它不是float):

EXEC sp_rename 'dbo.Miles.TotalDailyMiles', 'DailyMiles';
ALTER TABLE dbo.Miles ADD COLUMN AMMiles decimal(7, 2) NOT NULL
   CONSTRAINT DF_Miles_AMMiles DEFAULT (0);
ALTER TABLE dbo.Miles ADD COLUMN PMMiles decimal(7, 2) NOT NULL
   CONSTRAINT DF_Miles_PMMiles DEFAULT (0);
ALTER TABLE dbo.Miles ADD COLUMN TotalDailyMiles
   AS (DailyMiles + AMMiles + PMMiles) PERSISTED;

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,或AMMilesPMMiles必须都为0:

ALTER TABLE dbo.Miles ADD CONSTRAINT CK_Miles_DailyOrAMPM
   CHECK (DailyMiles = 0 OR (AMMiles = 0 AND PMMiles = 0));

只要数据的使用者不尝试更新TotalDailyMiles列,您就可以轻松解决问题。