从两个日期的最后两个日期派生的计算列表可能是空的

时间:2014-02-03 18:13:21

标签: sql-server tsql sql-server-2008-r2

是否可以创建一个计算列来处理另外两列,其中任何一列都可能为空?

我想在SQL Server 2008 R2中设置一个表,使其具有基于两个日期列的计算列。我已经能够创建一个基本的计算列,但我无法基于两列。基础日期列可以为null。请注意,null的结果是可接受的(当两个日期都为空时),但如果一个日期有效,则应使用该日期来计算自上次登录以来的天数。

以下是我到目前为止,计算出的LastLoginCount目前适用于一个日期列SHR_LastLogin,但我需要它来对两个日期列进行“最小化”(SHR_LastLoginAdLastLogin)并返回最新的登录信息。

CREATE TABLE [web].[UserNotifications](
    [NotificationId] [int] IDENTITY(1,1) NOT NULL,
    [AdDomain] [varchar](15) NULL,
    [AdAccount] [varchar](30) NULL,
    [AdFull]  AS (([AdDomain]+'\')+[AdAccount]),
    [AdLastLogin] [date] NULL,
    [SHR_LastLogin] [date] NULL,
    [ManagerNotifiedOn] [date] NULL,
    [NotifyManager] [bit] NOT NULL,
    [LastLoginCount]  AS (datediff(day,[SHR_LastLogin],getdate())),
 CONSTRAINT [PK_UserNotifications] PRIMARY KEY CLUSTERED 
(
    [NotificationId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

1 个答案:

答案 0 :(得分:2)

您无法在计算列中执行聚合,但您可以使用稍微丑陋的case语句进行设置(我首先想到的是,可能有更聪明的方法)。有关示例,请参阅此SQL Fiddle;它几乎归结为CREATE语句中的以下内容:

[LastLoginCount]    AS ( DATEDIFF( DAY, CASE
                        WHEN AdLastLogin > SHR_LastLogin
                          THEN AdLastLogin
                        ELSE SHR_LastLogin
                    END, GETDATE() ) ),

我告诉你,你指的是自登录以来的MIN天数;上面的代码已被编辑以将LessThan操作符交换为GreaterThan,但SQL Fiddle将继续显示前者。

修改:我没有初步了解/抓住NULL要求,对此表示歉意。它只需要在评估中进行一些调整,如this SQL Fiddle

[LastLoginCount]    AS ( DATEDIFF( DAY, CASE
                        WHEN AdLastLogin >= ISNULL( SHR_LastLogin, AdLastLogin ) 
                          THEN AdLastLogin
                        ELSE SHR_LastLogin
                    END, GETDATE() ) ),

实际上,逻辑是“如果SHR_LastLogin NULLAdLastLogin更大(或相等),请使用AdLastLogin;否则,请使用SHR_LastLogin [在DATEDIFF计算中]。"