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

时间:2012-11-29 12:55:18

标签: sql sql-server-2008

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

应根据列DOB的值计算此列的值。

此值也应随着Age的增加而增加。

4 个答案:

答案 0 :(得分:9)

您应该使用计算列来解决此问题。具有与此类似的定义的东西:

ALTER TABLE Customers ADD Age AS datediff(year, DOB ,getdate())

来自BlackWasp的原始陈述和更多信息。

编辑:

MSDN将计算列解释为:

  

计算列是根据可以使用其他的表达式计算的   同一个表中的列。表达式可以是非计算列   名称,常量,函数以及这些连接的任意组合   一个或多个运营商。表达式不能是子查询。

     

除非另有说明,否则计算列是虚拟列   没有物理存储在表中。他们的价值被重新计算   每次在查询中引用它们。数据库引擎使用   CREATE TABLE和ALTER TABLE语句中的PERSISTED关键字   在表中物理存储计算列。他们的价值观是   当计算中的任何列发生更改时更新。通过   将计算列标记为PERSISTED,您可以在a上创建索引   计算列是确定性但不精确的。另外,   如果计算列引用CLR函数,则为数据库引擎   无法验证该功能是否真正具有确定性。在这   case,计算列必须是PERSISTED,以便索引可以   在它上面创建。有关更多信息,请参阅在Computed上创建索引   列。

     

计算列可用于选择列表,WHERE子句,ORDER BY   条款,或正则表达式可以的任何其他位置   使用,但有以下例外:

     

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

     

例如,如果表具有整数列a和b,则计算列a + b可以是   索引,但计算列a + DATEPART(dd,GETDATE())无法索引,因为   值可能会改变>在随后的调用中。

     

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

     

数据库引擎自动确定可空性   根据使用的表达式计算列。结果最多   即使只有不可为空的列,表达式也被认为是可空的   存在,因为可能会产生下溢或溢出   null结果也是如此。使用COLUMNPROPERTY功能   AllowNull属性用于研究任何计算的可为空性   表中的列。可以为空的表达式可以转换为   通过指定ISNULL(check_expression,常量),不可空的,   其中常量是替换任何空结果的非空值。

来源:MSDN - Computed Columns

答案 1 :(得分: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 :(得分:2)

使用自动生成的列创建表

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

答案 3 :(得分: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