如何在 SQL Server 2008 表中创建计算列
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8725629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create a calculated column in a SQL Server 2008 table
提问by BI Dude
I really need a calculated column on a table with simple sum.
我真的需要一个简单总和的表格上的计算列。
Please see below:
请参阅以下内容:
SELECT key3
,SUM(UTOTALWBUD)
FROM CONTACT1
INNER JOIN CONTACT2
ON CONTACT1.ACCOUNTNO = CONTACT2.ACCOUNTNO
WHERE KEY1 = 'Client'
GROUP BY KEY3
I have tried to create a calculated column by adding following
我试图通过添加以下内容来创建一个计算列
ALTER TABLE ManagerTaLog
ADD WeeklyBudget as ( SELECT
key3
,SUM(UTOTALWBUD)
FROM CONTACT1
JOIN CONTACT2
ON CONTACT1.ACCOUNTNO = CONTACT2.ACCOUNTNO
WHERE KEY1 = 'Client'
GROUP BY KEY3)
I got the error message:
我收到错误消息:
Msg 1046, Level 15, State 1, Line 4
Subqueries are not allowed in this context. Only scalar expressions are allowed.
消息 1046,级别 15,状态 1,第 4 行
在此上下文中不允许子查询。只允许使用标量表达式。
Please advise what can I do about it.
请告知我该怎么办。
Many thanks
非常感谢
Part 2
第2部分
I have create a function; however, i get null values please advise.
我创建了一个函数;但是,我得到空值,请告知。
CREATE FUNCTION [dbo].[SumIt](@Key3 varchar)
RETURNS TABLE
AS
RETURN
(
SELECT SUM(UTOTALWBUD)
FROM CONTACT1
JOIN CONTACT2
ON CONTACT1.ACCOUNTNO = CONTACT2.ACCOUNTNO
JOIN Phone_List
ON CONTACT1.KEY3 = Phone_List.[Manager ]
WHERE KEY1 = 'Client'
AND Phone_List.[Manager ] = @Key3
GROUP BY [Manager ]
)
END
GO
Just select statment that returns values I wish to add to Phone_list table
只需选择返回我希望添加到 Phone_list 表的值的语句
SELECT [Manager ]
,SUM(UTOTALWBUD)
FROM CONTACT1
JOIN CONTACT2
ON CONTACT1.ACCOUNTNO = CONTACT2.ACCOUNTNO
JOIN Phone_List
ON CONTACT1.KEY3 = Phone_List.[Manager ]
WHERE KEY1 = 'Client'
GROUP BY [Manager ]
Table definitions
表定义
CREATE TABLE [dbo].[CONTACT1](
[ACCOUNTNO] [varchar](20) NOT NULL,
[COMPANY] [varchar](40) NULL,
[CONTACT] [varchar](40) NULL,
[LASTNAME] [varchar](15) NULL,
[DEPARTMENT] [varchar](35) NULL,
[TITLE] [varchar](35) NULL,
[SECR] [varchar](20) NULL,
[PHONE1] [varchar](25) NOT NULL,
[PHONE2] [varchar](25) NULL,
[PHONE3] [varchar](25) NULL,
[FAX] [varchar](25) NULL,
[EXT1] [varchar](6) NULL,
[EXT2] [varchar](6) NULL,
[EXT3] [varchar](6) NULL,
[EXT4] [varchar](6) NULL,
[ADDRESS1] [varchar](40) NULL,
[ADDRESS2] [varchar](40) NULL,
[ADDRESS3] [varchar](40) NULL,
[CITY] [varchar](30) NULL,
[STATE] [varchar](20) NULL,
[ZIP] [varchar](10) NOT NULL,
[COUNTRY] [varchar](20) NULL,
[DEAR] [varchar](20) NULL,
[SOURCE] [varchar](20) NULL,
[KEY1] [varchar](20) NULL,
[KEY2] [varchar](20) NULL,
[KEY3] [varchar](20) NULL,
[KEY4] [varchar](20) NULL,
[KEY5] [varchar](20) NULL,
[STATUS] [varchar](3) NOT NULL,
[NOTES] [text] NULL,
[MERGECODES] [varchar](20) NULL,
[CREATEBY] [varchar](8) NULL,
[CREATEON] [datetime] NULL,
[CREATEAT] [varchar](5) NULL,
[OWNER] [varchar](8) NOT NULL,
[LASTUSER] [varchar](8) NULL,
[LASTDATE] [datetime] NULL,
[LASTTIME] [varchar](5) NULL,
[U_COMPANY] [varchar](40) NOT NULL,
[U_CONTACT] [varchar](40) NOT NULL,
[U_LASTNAME] [varchar](15) NOT NULL,
[U_CITY] [varchar](30) NOT NULL,
[U_STATE] [varchar](20) NOT NULL,
[U_COUNTRY] [varchar](20) NOT NULL,
[U_KEY1] [varchar](20) NOT NULL,
[U_KEY2] [varchar](20) NOT NULL,
[U_KEY3] [varchar](20) NOT NULL,
[U_KEY4] [varchar](20) NOT NULL,
[U_KEY5] [varchar](20) NOT NULL,
[recid] [varchar](15) NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[Phone_List](
[Manager ] [nvarchar](255) NULL,
[SalesCode] [nvarchar](255) NULL,
[Email] [nvarchar](255) NULL,
[PayrollCode] [nvarchar](255) NULL,
[Mobile] [nvarchar](255) NULL,
[FName] [nchar](20) NULL,
[idd] [tinyint] NULL,
[OD] [varchar](20) NULL,
[WeeklyBudget] AS ([dbo].[SumIt]([manager]))
) ON [PRIMARY]
回答by Oleg Dok
You can wrap your query into the function like this (it HASto return one value):
你可以用你的查询到这样的(它的功能HAS返回一个值):
CREATE FUNCTION dbo.SumIt(@Key1 varchar(max))
returns float
as
begin
return (select sum(UTOTALWBUD) from
CONTACT1 inner join
CONTACT2 on
CONTACT1.ACCOUNTNO=CONTACT2.ACCOUNTNO
where KEY1=@key1
group by KEY3)
END
And use this function instead with calc field - something like this:
并使用此函数代替 calc 字段 - 如下所示:
alter table ManagerTaLog add WeeklyBudget as dbo.SumIt(Key1)
NOTE
笔记
that it will be the performance killer for queries like that:
它将成为这样的查询的性能杀手:
select * from ManagerTaLog
You should change your function in such a way, that is accept NOTvarchar
value, but NVARCHAR(255)
- the same type as Manager column. Try it.
您应该以这种方式更改您的功能,即接受NOTvarchar
值,但是NVARCHAR(255)
- 与 Manager 列的类型相同。尝试一下。
回答by Lieven Keersmaekers
If you resolve the issue of returning two values, one solution would be to implement the calculation in a function and use this function for the calculated column.
如果您解决了返回两个值的问题,一种解决方案是在函数中实现计算并将此函数用于计算列。
Some considerations
一些注意事项
- I have assumed that it is
Key3
that needs to be passed to the function and have added a where clause to return the weekly budget for the givenKey3
value. - The function will get executed for everyrecord in a resultset where you add the calculated column.
- 我假设它
Key3
需要传递给函数,并添加了一个 where 子句来返回给定Key3
值的每周预算。 - 该函数将对结果集中的每条记录执行,您在其中添加了计算列。
Script
脚本
CREATE FUNCTION dbo.fn_ManagerTaLogWeeklyBudget(@Key3 INTEGER) RETURNS INTEGER AS
BEGIN
select sum(UTOTALWBUD) from
CONTACT1 inner join
CONTACT2 on
CONTACT1.ACCOUNTNO=CONTACT2.ACCOUNTNO
where KEY1='Client'
AND KEY3 = @Key3
group by KEY3)
END
GO
ALTER TABLE dbo.ManagerTaLog
ADD WeeklyBudget AS dbo.fn_ManagerTaLogWeeklyBudget(Key3)
回答by marc_s
You cannot have a subquery that returns multiple valuesto be used as the computed column expression.
不能有返回多个值的子查询用作计算列表达式。
You can have an expression that returns a single value- or you can wrap your code in a stored function - or you can create a view (with a JOIN or subquery) that combines this logic into something you can use
您可以使用返回单个值的表达式- 或者您可以将代码包装在存储函数中 - 或者您可以创建一个视图(使用 JOIN 或子查询),将这个逻辑组合成您可以使用的东西
回答by Daniel
IMHO It is a wrong way. You have to use trigger on CONTACT tables and update WeeklyBudget in these triggers.
恕我直言,这是一种错误的方式。您必须在 CONTACT 表上使用触发器并在这些触发器中更新 WeeklyBudget。
回答by Gopakumar N.Kurup
CREATE FUNCTION [dbo].[SumIt](@Key3 varchar)
RETURNS TABLE
AS
RETURN
(
SELECT SUM(ISNULL(UTOTALWBUD,0))
FROM CONTACT1
JOIN CONTACT2
ON CONTACT1.ACCOUNTNO = CONTACT2.ACCOUNTNO
JOIN Phone_List
ON CONTACT1.KEY3 = Phone_List.[Manager ]
WHERE KEY1 = 'Client'
AND Phone_List.[Manager ] = @Key3
GROUP BY [Manager ]
)
END
GO
Hope this will help. Please note that this is not a proper solution, but this may help your particular scenario. Since the function is returning multiple values, you can either user a table valued function or just modify the query in a way that it will return only one value. But if the column is nullable please don't forget to add ISNULL.
希望这会有所帮助。请注意,这不是一个正确的解决方案,但这可能对您的特定情况有所帮助。由于该函数返回多个值,您可以使用表值函数或仅以仅返回一个值的方式修改查询。但如果该列可以为空,请不要忘记添加 ISNULL。
回答by mshthn
You can have calculated columns in a table but that will be present (and calculated) in all rows of the table. The thing what you're trying to do in your select is called "aggregate". Try this:
您可以在表中计算列,但这些列将出现(并计算)在表的所有行中。您在选择中尝试做的事情称为“聚合”。尝试这个:
select key3, sum(UTOTALWBUD) as WeeklyBudget from
CONTACT1 inner join CONTACT2 on CONTACT1.ACCOUNTNO=CONTACT2.ACCOUNTNO
where KEY1='Client'
group by key3