如何创建从另一列计算的列?
Posted
技术标签:
【中文标题】如何创建从另一列计算的列?【英文标题】:How do I create column calculated from another column? 【发布时间】:2012-11-29 12:55:18 【问题描述】:我需要在 SQL Server 数据库中创建一个列 age
。
此列的值应根据DOB
列的值计算。
它的值也应该随着Age
的增加而增加。
【问题讨论】:
那么新添加的行呢? 只有当您选择表的值时,或者更确切地说,当您访问时,任何人都会知道年龄是否是最新的。所以你可以使用触发器/存储过程来做到这一点..不是吗? something on similar lines 我只需在表格顶部创建一个视图,视图定义的最后一列为datediff(yy, DOB, getUTCDate())
。
创建一个计算年龄的视图。无需存储此类信息。
哦,看,一个家庭作业问题:-)
【参考方案1】:
您应该使用计算列来解决此问题。类似这样定义的东西:
ALTER TABLE Customers ADD Age AS datediff(year, DOB ,getdate())
来自BlackWasp 的原始声明和更多信息。
编辑:
MSDN 将计算列解释为:
计算列是根据可以使用其他表达式的表达式计算得出的 同一个表中的列。表达式可以是非计算列 名称、常量、函数以及它们的任意组合 一名或多名运营商。表达式不能是子查询。
除非另有说明,否则计算列是虚拟列 没有物理存储在表中。重新计算它们的值 每次在查询中引用它们时。数据库引擎使用 CREATE TABLE 和 ALTER TABLE 语句中的 PERSISTED 关键字 将计算列物理存储在表中。他们的价值观是 当作为其计算一部分的任何列发生更改时更新。经过 将计算列标记为 PERSISTED,您可以在 确定性但不精确的计算列。此外, 如果计算列引用 CLR 函数,则数据库引擎 无法验证函数是否真正具有确定性。在这 在这种情况下,计算列必须是 PERSISTED 以便索引可以 在其上创建。有关更多信息,请参阅在 Computed 上创建索引 列。
计算列可用于选择列表、WHERE 子句、ORDER BY 子句或任何其他可以使用正则表达式的位置 使用,但以下情况除外:
必须标记用作 CHECK、FOREIGN KEY 或 NOT NULL 约束的计算列 坚持。计算列可以用作索引中的键列或任何 PRIMARY KEY 或 UNIQUE 约束,如果计算的列值由 确定性表达式和结果的数据类型在索引中是允许的 列。
例如,如果表具有整数列 a 和 b,则计算列 a + b 可以是 已编入索引,但计算列 a + DATEPART(dd, GETDATE()) 无法编入索引,因为 值可能会在随后的调用中发生变化。
计算列不能是 INSERT 或 UPDATE 语句的目标。
数据库引擎自动确定可空性 根据使用的表达式计算列。大多数的结果 即使只有不可为空的列,表达式也被认为可以为空 存在,因为可能会产生下溢或上溢 空结果也是如此。将 COLUMNPROPERTY 函数与 AllowsNull 属性来调查任何计算的可空性 表中的列。可以为空的表达式可以转换为 通过指定 ISNULL(check_expression, constant) 的不可为空的一个, 其中常量是一个非空值,替换为任何空结果。
来源:MSDN - Computed Columns
【讨论】:
我建议您也在这里添加一些信息,而不仅仅是链接。就像什么是计算列一样,它可以被持久化,可以被索引等等。 完成。我冒昧地引用了 MSDN 很好的描述,但是真的找不到年代。它发现 2 个日期之间的整年差异。出生日期 = '2012-12-31',getdate() = '2013-01-01' = 1 年【参考方案2】:代码sn-p
ALTER TABLE
TheTable
ADD
DOB AS
CASE
WHEN
MONTH(Birth) > MONTH(ISNULL(Death, SYSDATETIME()))
OR (
MONTH(Birth) = MONTH(ISNULL(Death, SYSDATETIME()))
AND DAY(Birth) >= DAY(ISNULL(Death, SYSDATETIME()))
)
THEN
DATEDIFF(YEAR, Birth, ISNULL(Death, SYSDATETIME())) - 1
ELSE
DATEDIFF(YEAR, Birth, ISNULL(Death, SYSDATETIME()))
END
【讨论】:
【参考方案3】:使用自动生成的列创建表,
CREATE TABLE Person2
(Id int IDENTITY(1,1) NOT NULL, Name nvarchar(50),
DOB date, Age AS DATEDIFF(YEAR, DOB ,GETDATE()) )
【讨论】:
【参考方案4】:这是获取年龄的正确方法:
alter table <yourtable> add age as datediff(year, DOB, getdate())- case when month(DOB)*32 + day(DOB) > month(getdate()) * 32 + day(getdate()) then 1 else 0 end
【讨论】:
以上是关于如何创建从另一列计算的列?的主要内容,如果未能解决你的问题,请参考以下文章