Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 基于不同表格的计算列公式';s柱_Sql_Sql Server 2008_Calculated Columns - Fatal编程技术网

Sql 基于不同表格的计算列公式';s柱

Sql 基于不同表格的计算列公式';s柱,sql,sql-server-2008,calculated-columns,Sql,Sql Server 2008,Calculated Columns,考虑一下这个表:c_const code | nvalue -------------- 1 | 10000 2 | 20000 和另一个表t_anytable rec_id | s_id | n_code --------------------- 2 | x | 1 目标是使s_id成为一个计算列,基于以下公式: rec_id*(select nvalue from c_const where code=ncode)

考虑一下这个表:
c_const

 code  |  nvalue
 --------------
 1     |  10000
 2     |  20000  
和另一个表
t_anytable

 rec_id |  s_id  | n_code
 ---------------------
 2      |  x     | 1
目标是使
s_id
成为一个计算列,基于以下公式:

 rec_id*(select nvalue from c_const where code=ncode)
这会产生一个错误:

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


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

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

CREATE FUNCTION dbo.GetValue(@ncode INT, @recid INT)
RETURNS INT
AS 
   SELECT @recid * nvalue 
   FROM c_const 
   WHERE code = @ncode
然后使用它来定义计算列:

ALTER TABLE dbo.YourTable
   ADD NewColumnName AS dbo.GetValue(ncodeValue, recIdValue)
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

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

这与子查询版本有一个细微的区别,即如果联接有多个结果,它将返回多个记录,而不是生成错误。但这很容易通过
c_const.code
唯一
约束来解决(我怀疑它已经是
主键了)

它也比子查询版本更容易让人理解


正如marc_s所示,您可以使用子查询和自定义项来实现,但与简单的
联接相比,这可能是非常低效的,因为标量自定义项需要逐行计算。

@marc_s:没关系,谢谢您的帮助。当其他表更新时,计算字段会被更新吗?@littlestewie:是的!每当某段代码访问该
NewColumnName
列时,该函数将被调用,值将被删除calculated@Binny,marc_s:我不会说UDF会像视图一样有效。视图对查询优化程序是透明的,而UDF本质上是一个黑盒。UDF将有自己的执行计划,并始终为每个受影响的行运行,而视图将与查询的其余部分混合,并且始终为使用该视图的整个查询生成最佳执行计划。在Management studio中将计算字段的IsPersisted属性设置为True。然后,它不会在每次访问该字段时重新计算。或者在DDL中,在字段的公式后添加persistend,例如ALTER TABLE dbo.YourTable Add NewColumnName AS dbo.GetValue(ncodeValue,recIdValue)persistend;值得注意的是,只有在值是确定性的情况下才能使用持久化-请参阅详细信息注意,索引视图并不总是“快速查找”-如果索引视图存储的行数与基表的行数相同(例如,它不是聚合),并且也不比基表小很多,它不会更快——在类似这样的情况下,计算列比索引视图IMHO更好……或者如果它比基表更瘦,但您仍然必须与基表联接以满足查询。在我的经验中,索引视图的主要优势始终是减少了计算聚合的存储,而不是删除计算本身。我将修改我的评论,因为我显然没有阅读这里的全部内容,也没有意识到要求从不同的表中提取值。在这种情况下,索引视图可能是一个很好的解决方案,我的反对意见只是关于一个常见的误解(在这里是永久性的),即索引视图总是比普通视图或计算列更快。