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更好……或者如果它比基表更瘦,但您仍然必须与基表联接以满足查询。在我的经验中,索引视图的主要优势始终是减少了计算聚合的存储,而不是删除计算本身。我将修改我的评论,因为我显然没有阅读这里的全部内容,也没有意识到要求从不同的表中提取值。在这种情况下,索引视图可能是一个很好的解决方案,我的反对意见只是关于一个常见的误解(在这里是永久性的),即索引视图总是比普通视图或计算列更快。