如何创建从另一列计算的列?

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

【讨论】:

以上是关于如何创建从另一列计算的列?的主要内容,如果未能解决你的问题,请参考以下文章

如何计算另一列中特定值的列的平均值?

我需要使用索引和匹配从另一列条件匹配的列中提取数据

点击屋。如何创建一个保留另一列的最后一个值的列?

redshift update 命令从另一列设置值,该列名是标识符

如何在另一列中按条件分组的列中查找下一个日期?

jquery datatable - 如何使用渲染函数从另一列获取数据