-1

我有下表:

ID   ActualDt   DueDt     Flag
--   -------    -------   ----    
1    01/03/12   09/13/12   Y
2    NULL       07/12/12   Y 
3    NULL       09/12/12   N
4    02/03/12   01/13/12   N

对于以下情况,我需要将 Flag 标记为 Y:

1) 如果 ActualDt 不为 null 且 DueDt 不为 null 且 DueDt > ActualDt

2) 如果 ActualDt 为空且 DueDt 根据当前日期过期

否则,标志 = N

注意 ActualDt 是一个字符串

我将如何在 t-sql 中对此进行编程

我知道我需要一个案例陈述。

4

3 回答 3

2

如果我正确理解您的逻辑,它应该是:

SELECT
ID,
ActualDt,
DueDt,
CASE 
     WHEN ActualDt IS NOT NULL AND DueDt IS NOT NULL AND DueDt > ActualDt THEN 'Y'
     WHEN ActualDt IS NULL AND DueDt < getdate() THEN 'Y'
     ELSE 'N'
END as Flag
FROM YourTable

编辑:正如 Aaron(像往常一样!)指出的那样,我错过了您使用字符串作为日期。由于您将 ActualDt 存储为字符串,因此不会为您提供正确的结果

您可以将所有日期值转换为日期时间...

SELECT
ID,
ActualDt,
DueDt,
CASE 
     WHEN cast(ActualDt as datetime) IS NOT NULL AND cast(DueDt as datetime) IS NOT NULL AND cast(DueDt as datetime) > cast(ActualDt as datetime) THEN 'Y'
     WHEN cast(ActualDt as datetime) IS NULL AND cast(DueDt as datetime) < getdate() THEN 'Y'
     ELSE 'N'
END as Flag
FROM YourTable

但请注意,根据日期格式和您的语言环境设置(和日期格式设置),您可能会遇到 SQL 错误或意外日期。

将日期存储为日期时间总是更好 - 你能解释为什么你的日期是字符串吗?

于 2012-08-13T21:47:28.067 回答
0

您需要一个更新声明:

update t
    set flag = (case when ActualDt is not null and DueDt is not null and
                          DueDt > cast(ActualDt as date)
                     then 'Y'
                     when ActualDt is null and DueDt is not null and
                          DueDt > cast(CURRENT_TIMESTAMP as date)
                     then 'Y'
                     else 'N'
                end)

此查询假定日期格式与数据库的默认格式相匹配。我的数据库设置为美国标准,因此 '01/03/12' 被解释为 2012 年 1 月 3 日。

于 2012-08-13T21:52:30.140 回答
0

为了让您的生活更轻松,真正的解决方案是停止将日期存储为字符串。假设您最初是从这张表开始的:

CREATE TABLE dbo.Nathan
(
 ID INT,   
 ActualDt VARCHAR(32),  
 DueDt VARCHAR(32),     
 Flag CHAR(1)
);
GO

INSERT dbo.Nathan VALUES
(1,'01/03/12','09/13/12','Y'),
(2, NULL     ,'07/12/12','Y'), 
(3, NULL     ,'09/12/12','N'),
(4,'02/03/12','01/13/12','N');

让我们首先让你的字符串完全明确:

UPDATE dbo.Nathan
  SET ActualDt = CONVERT(CHAR(10), CONVERT(DATETIME, ActualDt, 1), 120),
      DueDt    = CONVERT(CHAR(10), CONVERT(DATETIME, DueDt   , 1), 120);

现在让我们更正数据类型:

ALTER TABLE dbo.Nathan ALTER COLUMN ActualDt DATE;
ALTER TABLE dbo.Nathan ALTER COLUMN DueDt DATE;
-- you should also update any parameters or code where
-- explicit types are used to populate these columns

现在您的数据使用正确的数据类型存储,并且可以在没有所有这些混乱的字符串解释和数据类型转换的情况下进行比较。您的要求是:

对于以下情况,我需要将 Flag 标记为 Y:
1) 如果 ActualDt 不为 null 且 DueDt 不为 null 且 DueDt > ActualDt
2) 如果 ActualDt 为 null 且 DueDt 基于当前日期过期
否则,Flag = N

对我来说是这样写的:

UPDATE dbo.Nathan
  SET Flag = CASE WHEN DueDt > ActualDt
    OR (ActualDt IS NULL AND DueDt < CURRENT_TIMESTAMP)
  THEN 'Y' ELSE 'N' END;

结果:

ID  ActualDt    DueDt       Flag
--  ----------  ----------  ----
1   2012-01-03  2012-09-13  Y  -- DueDt > ActualDt
2   NULL        2012-07-12  Y  -- past due
3   NULL        2012-09-12  N  -- not past due
4   2012-02-03  2012-01-13  N  -- DueDt NOT > ActualDt

我认为,这比继续将日期存储为字符串要好得多。

于 2012-08-14T12:19:39.077 回答