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

7

我需要在SQL Server数据库中创建一个名为age的列。

这一列的值应该基于DOB列的值进行计算。

此外,随着Age的增加,它的值也应该递增。


新增的行呢? - indiPy
只有在您选择表的值或者访问任何人时,才会知道年龄是否是最新的。因此,您可以使用触发器/存储过程来完成这个任务,不是吗? 类似于这样的内容 - bonCodigo
我会在表上创建一个 VIEW,其中视图定义的最后一列为 datediff(yy, DOB, getUTCDate()) - Vikdor
创建一个视图来计算年龄。无需存储此类信息。 - user330315
哦,看起来是一道作业题 :-) - CResults
4个回答

10
你应该使用计算列来解决这个问题。定义类似于这样的内容:
ALTER TABLE Customers ADD Age AS datediff(year, DOB ,getdate())

原声明摘自并获取更多信息请访问BlackWasp.

编辑:

MSDN将计算列解释为:

  

计算列是从可以使用同一表中的其他列的表达式计算出来的。该表达式可以是非计算列名称、常量、函数和任何这些组合,由一个或多个运算符连接。表达式不能是子查询。

     

除非另有说明,否则计算列是虚拟列,不会在表中实际存储。它们的值每次在查询中引用时都会重新计算。数据库引擎在CREATE TABLE和ALTER TABLE语句中使用PERSISTED关键字来物理存储计算列。当它们计算中所涉及的任何列发生变化时,它们的值会更新。通过将计算列标记为PERSISTED,可以在计算列上创建一个确定性但不精确的索引。此外,如果计算列引用CLR函数,则数据库引擎无法验证函数是否真正确定。在这种情况下,必须PERSISTED计算列,以便可以在其上创建索引。有关详细信息,请参阅在计算列上创建索引。

     

计算列可用于select列表、WHERE子句、ORDER BY子句或任何其他可用正则表达式的位置,但以下情况除外:

     

计算列用作CHECK、FOREIGN KEY或NOT NULL约束必须标记为PERSISTED。如果计算列值由确定性表达式定义,并且结果数据类型允许在索引列中使用,则可以将计算列用作索引中的关键列或任何PRIMARY KEY或UNIQUE约束的一部分。

     

例如,如果表具有整数列a和b,则可以索引计算列a + b,但不能索引计算列a + DATEPART(dd, GETDATE()),因为该值可能会在后续调用中更改。

     

计算列不能成为INSERT或UPDATE语句的目标。

     

数据库引擎基于所使用的表达式自动确定计算列的可空性。大多数表达式的结果即使只存在不可空列也被认为是可空的,因为可能出现下溢或溢出也会产生null结果。使用COLUMNPROPERTY函数与AllowsNull属性来调查表中任何计算列的可空性。可为空的表达式可以通过指定ISNULL(check_expression,constant)将其转换为不可为空的表达式,其中constant是替代任何null结果的非null值。

来源:MSDN - Computed Columns


我建议您在这里添加一些信息,而不仅仅是链接。例如,什么是计算列,它是否可以持久化,是否可以索引等等。 - ypercubeᵀᴹ
完成。我已经引用了MSDN的内容。 - SchmitzIT
1
非常好的描述,但它实际上并没有找到年龄。它找到了两个日期之间整年的差异。DOB = '2012-12-31',getdate() = '2013-01-01' = 1年。 - t-clausen.dk

4

代码片段

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

2

使用自动生成列创建表格

CREATE TABLE Person2
(Id int IDENTITY(1,1) NOT NULL, Name nvarchar(50),
DOB date, Age AS DATEDIFF(YEAR, DOB ,GETDATE()) )

1

这是获取年龄的正确方式:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接