如何在 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 表中创建计算列的主要内容,如果未能解决你的问题,请参考以下文章

怎么在 sql server 2008中创建登录名

如何在 Python 中使用表值参数访问 SQL Server 2008 存储过程

如何使用 SQL Server Management Studio (2008) 在 SQL Server Compact Edition 中创建列

如何在 SQL Server Express 2008 中创建新数据库并允许连接?

如何在 SQL Server 中创建一个接受一列数据的函数?

如何在 SQL 2008 R2 的表中创建 AutoCounter 列?