如何在 SQL Server 2008 表中创建计算列
Posted
技术标签:
【中文标题】如何在 SQL Server 2008 表中创建计算列【英文标题】:How to create a calculated column in a SQL Server 2008 table 【发布时间】:2012-01-04 10:54:48 【问题描述】:我真的需要一个简单求和的表格上的计算列。
请看下面:
SELECT key3
,SUM(UTOTALWBUD)
FROM CONTACT1
INNER JOIN CONTACT2
ON CONTACT1.ACCOUNTNO = CONTACT2.ACCOUNTNO
WHERE KEY1 = 'Client'
GROUP BY KEY3
我尝试通过添加以下内容来创建计算列
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)
我收到错误消息:
消息 1046,第 15 级,状态 1,第 4 行 在这种情况下不允许子查询。只允许使用标量表达式。
请告诉我该怎么做。
非常感谢
第 2 部分
我已经创建了一个函数;但是,我得到空值请告知。
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
只需选择返回值的语句,我希望添加到 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 ]
表定义
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]
【问题讨论】:
您的子查询返回 两个值 - 这将如何存储在单个计算列中?!?!?!? 向我们展示表定义。你确定 Key3 有值吗? 不确定是否相关,但您使用([dbo].[SumIt]([manager]))
而不是 ([dbo].[SumIt]([manager ]))
调用函数(注意额外的空格)。
【参考方案1】:
您可以将查询包装到这样的函数中(它有返回一个值):
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
并将此函数与 calc 字段一起使用 - 如下所示:
alter table ManagerTaLog add WeeklyBudget as dbo.SumIt(Key1)
注意
它将成为此类查询的性能杀手:
select * from ManagerTaLog
您应该以这样的方式更改您的函数,即接受 NOT varchar
值,但接受 NVARCHAR(255)
- 与 Manager 列相同的类型。试试看。
【讨论】:
【参考方案2】:如果您解决了返回两个值的问题,一种解决方案是在函数中实现计算并将该函数用于计算列。
一些注意事项
我假设需要传递给函数的是Key3
,并添加了 where 子句以返回给定 Key3
值的每周预算。
该函数将为您添加计算列的结果集中的每条记录执行。
脚本
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)
【讨论】:
感谢您的帖子。我创建了函数并更改了表;但是,结果给了我空值 @user995506 - 我在 20 小时前对您的问题发表的评论怎么样?【参考方案3】:您不能将返回多个值的子查询用作计算列表达式。
您可以有一个返回单个值的表达式 - 或者您可以将代码包装在存储的函数中 - 或者您可以创建一个视图(使用 JOIN 或子查询)将此逻辑组合到你可以使用的东西
【讨论】:
【参考方案4】:恕我直言,这是错误的方法。您必须在 CONTACT 表上使用触发器并在这些触发器中更新 WeeklyBudget。
【讨论】:
【参考方案5】:您可以在表格中包含计算的列,但这些列将出现(并计算)在表格的所有行中。 您在选择中尝试执行的操作称为“聚合”。试试这个:
select key3, sum(UTOTALWBUD) as WeeklyBudget from
CONTACT1 inner join CONTACT2 on CONTACT1.ACCOUNTNO=CONTACT2.ACCOUNTNO
where KEY1='Client'
group by key3
【讨论】:
【参考方案6】: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
希望这会有所帮助。请注意,这不是一个正确的解决方案,但这可能有助于您的特定情况。由于该函数返回多个值,因此您可以使用表值函数,也可以只修改查询以使其仅返回一个值。但如果该列可以为空,请不要忘记添加 ISNULL。
【讨论】:
以上是关于如何在 SQL Server 2008 表中创建计算列的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Python 中使用表值参数访问 SQL Server 2008 存储过程
如何使用 SQL Server Management Studio (2008) 在 SQL Server Compact Edition 中创建列
如何在 SQL Server Express 2008 中创建新数据库并允许连接?