计算列的公式基于不同的表列

Adn*_*KEN 47 sql calculated-columns sql-server-2008

考虑一下这个表: c_const

 code  |  nvalue
 --------------
 1     |  10000
 2     |  20000  
Run Code Online (Sandbox Code Playgroud)

和另一张桌子 t_anytable

 rec_id |  s_id  | n_code
 ---------------------
 2      |  x     | 1
Run Code Online (Sandbox Code Playgroud)

目标是s_id基于以下公式成为计算列:

 rec_id*(select nvalue from c_const where code=ncode)
Run Code Online (Sandbox Code Playgroud)

这会产生错误:

在此上下文中不允许子查询.只允许标量表达式.

如何使用另一个表的列作为输入来计算此计算列的值?

mar*_*c_s 72

您可以为此创建用户定义的函数:

CREATE FUNCTION dbo.GetValue(@ncode INT, @recid INT)
RETURNS INT
AS 
   SELECT @recid * nvalue 
   FROM c_const 
   WHERE code = @ncode
Run Code Online (Sandbox Code Playgroud)

然后使用它来定义您的计算列:

ALTER TABLE dbo.YourTable
   ADD NewColumnName AS dbo.GetValue(ncodeValue, recIdValue)
Run Code Online (Sandbox Code Playgroud)

  • @Binny,marc_s:我不会说UDF会像视图那样高效.视图对查询优化器是透明的,而UDF本质上是黑盒子.UDF将有自己的执行计划,并且总是为受影响的每一行*运行*,而视图将与查询的其余部分混合,并且将始终为使用该视图的整个查询*生成*的最佳执行计划. (8认同)
  • 值得注意的是,如果值是确定性的,则只能使用PERSISTED - 请参阅https://docs.microsoft.com/en-us/sql/relational-databases/user-defined-functions/deterministic-and-nondeterministic-functions for细节 (4认同)
  • 每当更新另一个表时,计算字段是否会更新? (2认同)
  • @littlestewie:**yes!**每当某段代码访问"NewColumnName"列时,将调用该函数并计算该值 (2认同)
  • @Binny:就像在视图中计算它一样有效... (2认同)

Aar*_*ght 24

这似乎更像是视图的工作(索引视图,如果您需要在计算列上快速查找):

CREATE VIEW AnyView
WITH SCHEMABINDING
AS

SELECT a.rec_id, a.s_id, a.n_code, a.rec_id * c.nvalue AS foo
FROM AnyTable a
INNER JOIN C_Const c
    ON c.code = a.n_code
Run Code Online (Sandbox Code Playgroud)

这与子查询版本有细微差别,因为如果连接有多个结果,它将返回多个记录而不是产生错误.但这很容易通过UNIQUE约束来解决c_const.code(我怀疑它已经是一个PRIMARY KEY).

对于某人来说,理解它比子查询版本容易得多.

您可以使用子查询和UDF来执行此操作,正如marc_s所示,但与简单相比,这可能是非常低效的JOIN,因为标量UDF将需要逐行计算.

  • 我将修改我的评论,因为我显然没有在这里阅读整个上下文,并没有意识到要求是从另一个表中提取值.在这种情况下,索引视图可能是一个很好的解决方案,我的反对意见仅仅是关于索引视图总是比普通视图或计算列更快的常见误解(以及此处的永久化). (2认同)