如何在表中指定基于 SQL Server 中另一列的计算列?

Posted

技术标签:

【中文标题】如何在表中指定基于 SQL Server 中另一列的计算列?【英文标题】:How do I Specify Computed Columns in a Table which are based on another Column in SQL Server? 【发布时间】:2015-06-09 18:42:27 【问题描述】:

我有以下捏造的数据。

我想更改 Total_Investment 列以使其成为计算列,该列计算该行中存在的单位名称的总 Dollar_Amount。

例如,对于第 1 行,Total_Investment 槽将显示列为“Healthy_Communities”的两行的总和,因此第 1 行和第 6 行,例如,5899.00 + 1766.00。

第 2 行将汇总所有三个城市条目(2、5 和 9),依此类推。如何在 SQL Sever 2012 中完成此操作?

Project_ID  Unit_Name             Fiscal_Year  Dollar_Amount  Total_Investment
1           Healthy Communities   2000-01-01   5899.00        0.00
2           Urban                 2009-01-01   6008.00        0.00
3           Rivers and Watersheds 2006-01-01   6835.00        0.00
4           Large Landscapes      2011-01-01   5216.00        0.00
5           Urban                 2015-01-01   3555.00        0.00
6           Healthy Communities   2014-01-01   1766.00        0.00
7           Youth Engagement      2004-01-01   4246.00        0.00
8           Rivers and Watersheds 2014-01-01   8253.00        0.00
9           Urban                 2000-01-01   5590.00        0.00
10          Outdoor Recreation    2013-01-01   5356.00        0.00

我知道 alter table documentation 用于计算列,但不知道如何修改此代码以适应我的问题。

【问题讨论】:

可以使用 UDF 来完成。 google.com/… 嗯,好点,我可能应该写一个过程。谢谢! 为什么不创建视图?比如:create view NameIt as select Unit_Name, sum(Dollar_Amount) from YourTable group by Unit_Name 这对我来说似乎是个坏主意。您正在添加一个新列,该列是跨详细信息行的聚合数据。呸!! 【参考方案1】:

是的,您将创建一个用户定义的函数来进行计算并在 Computed 列的表达式中使用该用户定义的函数。

一个可行的例子是.....

CREATE TABLE TABLE1 (ID INT, VALUE INT)
GO
INSERT INTO TABLE1 VALUES (1 , 10), (2 , 20) , (3 , 30)
GO

CREATE FUNCTION dbo.udf_DefaultValue(@ID INT)
RETURNS INT
AS
BEGIN
    DECLARE @rtnValue INT;
    SELECT @rtnValue = VALUE *2 FROM TABLE1 WHERE ID = @ID
    RETURN @rtnValue;
END
GO

CREATE TABLE TABLE2 (ID INT
                  , VALUE INT
                  , ComputedColumn AS (VALUE * dbo.udf_DefaultValue(ID)) )
GO

INSERT INTO TABLE2 (ID , VALUE)
VALUES (1, 1)

SELECT * FROM TABLE2

/*****  Result Set  *****/

ID  VALUE   ComputedColumn
1     1           20

【讨论】:

【参考方案2】:

仅将下面的 MyTable 替换为您的表名称。 这种方法的缺点是,如果处理多行(例如 10000 行需要 40 秒),它会变得非常昂贵。对于这种情况,您可以使用视图。 (感谢@Amit 对UDF 的坚持。对不起,表演太棒了)

编辑: 在Unit_Name 上添加了非聚集索引,包括Dollar_Amount。性能提高了十倍。

-- drop table MyTable;
-- drop function udfMyTable;

-- go

create table MyTable(
 project_id int identity(1, 1) primary key,
 Unit_Name varchar(120),
 Dollar_Amount decimal(19, 2),
)

go
create nonclustered index IX_Unit on dbo.MyTable(Unit_Name) include (Dollar_Amount);

create function udfMyTable (@pk as int)
returns decimal(19, 2)
as
begin
declare @res as decimal(19, 2);
select 
    @res=sum(Dollar_Amount) 
from 
    MyTable 
where Unit_Name in (select Unit_Name from MyTable where project_id=@pk);
return @res;
end
go
alter table MyTable add Total_Amount as dbo.udfMyTable(project_id)
go


insert into MyTable (unit_name, dollar_amount) values
('Healthy Communities',   '5899.00'),
('Urban',                 6008.00),
('Rivers and Watersheds', 6835.00),
('Large Landscapes',      5216.00),
('Urban',                 3555.00),
('Healthy Communities',   1766.00),
('Youth Engagement',      4246.00),
('Rivers and Watersheds', 8253.00),
('Urban',               5590.00),
('Outdoor Recreation', 5356.00)

select * from MyTable;

【讨论】:

以上是关于如何在表中指定基于 SQL Server 中另一列的计算列?的主要内容,如果未能解决你的问题,请参考以下文章

sql server 中有一张表,我想把表中两列的数据合并后插入本表中另一列!请问怎么实现

我如何基于Awk中另一列中的值求和列中的值

基于 DataFrame 中另一列的列的滚动总和

获取 SQL 中另一列的每个值的最常见值

基于 Pandas 中另一列文本的特征工程师文本

基于Scala中另一列的值映射RDD列