2010-08-09 27 views
2
ID Level Effective Date ExpirationDate 
000012-12  2 12/01/2005 NULL 
000012-12 1 12/01/2005 NULL 
000012-12 2 12/01/2005 01/01/2009 
000012-A12 2 10/01/1994 11/30/2005 
000012-A12 2 01/01/1999 11/30/2005 
000012-A12 2 09/01/2001 11/30/2005 
000012-A12 1 12/01/2005 12/31/2007 

只有最新的记录才会被提取。这意味着在上述情况下
预计日期 - 如果null该记录仍然有效。
如果大于当前时间戳,则其未来的过期日期意味着仍然有效。
如果小于当前时间标记,则终止。
大部分当前是最活跃或最新的终止记录。如果它已经激活并终止,那么只显示激活。否则上次终止的记录。请选择其他条件的最新记录

一个ID可以有相同的生效日期和日期但有多个级别的2行。所以在这种情况下,我们只需要为第一级选择一条记录。

所以按照上述数据设置如下是预期输出

输出

000012-12 1 12/01/2005 NULL 
000012-A12 2 12/01/2005 01/01/2009 

请帮

托马斯。请查看以下数据集。

Insert #Test(Id, Level, EffectiveDate, ExpirationDate) Values ('000872-A24',1,'1994-10-01',NULL); 
Insert #Test(Id, Level, EffectiveDate, ExpirationDate) Values ('000872-A24',1,'1999-01-01',NULL); 
Insert #Test(Id, Level, EffectiveDate, ExpirationDate) Values ('000872-A24',2,'2001-09-01',NULL); 
Insert #Test(Id, Level, EffectiveDate, ExpirationDate) Values ('000872-A24',1,'2003-01-01','2007-12-31'); 

当您运行查询它应该给

000872-A24 2 2001年9月1日空

,但现在它返回

000872-A24 1 01/01/2003 12/31/2007

+0

对于什么数据库? – 2010-08-09 00:20:07

+0

@ sqllearner190 - 表有一个主键,如auto_increment或标识列吗? – Thomas 2010-08-09 00:23:46

+0

@ sqllearner190 - 您能否在您的示例数据中演示需要项目#2的第二个条件的情况? – Thomas 2010-08-09 00:26:26

回答

1

如果不知道数据库产品,很难提供答案。

1. if there is no auto_increment/identity column 
2. and if there is no other primary key (which is a bad idea obviously) 
3. and if the given database product supports `CURRENT_TIMESTAMP` (each DBMS will likely have some equivalent to the current date and time) 
4. and if the target date by which you measure "latest" is the current date and time 


Select Id, Level 
From Table As T 
Where T. EffectiveDate = (
          Select Max(T2.EffectiveDate) 
          From Table As T2 
          Where T2.ID = T.ID 
           And (T2.EffectiveDate Is Null 
            Or (
             CURRENT_TIMESTAMP >= T2.EffectiveDate 
             And CURRENT_TIMESTAMP <= T2.ExpirationDate 
             ) 
            ) 
          ) 

你会注意到我的答案中的一些注意事项。这表明我们需要更多信息:

  1. 什么数据库产品和版本?
  2. 桌子上是否有一个auto_incrementing唯一键?
  3. 该级别如何适合你想要的结果? (请扩展您的示例数据以包含边缘案例)。
  4. 如果当前日期和时间早于有效日期到期日期,应该发生什么情况?

编辑

现在我们知道你使用的是SQL Server 2008中,这使得解决方案更容易:

If object_id('tempdb..#Test') is not null 
    Drop Table #Test; 
GO 
Create Table #Test (
        PkCol int not null identity(1,1) Primary Key 
        , Id varchar(50) not null 
        , Level int not null 
        , EffectiveDate datetime not null 
        , ExpirationDate datetime null 
        ); 

Insert #Test(Id, Level, EffectiveDate, ExpirationDate) Values ('000012-12',2,'12/01/2005',NULL); 
Insert #Test(Id, Level, EffectiveDate, ExpirationDate) Values ('000012-12',1,'12/01/2005',NULL); 
Insert #Test(Id, Level, EffectiveDate, ExpirationDate) Values ('000012-12',2,'12/01/2005','01/01/2009'); 
Insert #Test(Id, Level, EffectiveDate, ExpirationDate) Values ('000012-A12',2,'10/01/1994','11/30/2005'); 
Insert #Test(Id, Level, EffectiveDate, ExpirationDate) Values ('000012-A12',2,'01/01/1999','11/30/2005'); 
Insert #Test(Id, Level, EffectiveDate, ExpirationDate) Values ('000012-A12',2,'09/01/2001','11/30/2005'); 
Insert #Test(Id, Level, EffectiveDate, ExpirationDate) Values ('000012-A12',1,'12/01/2005','12/31/2007'); 

With Items As 
    (
    Select PkCol, Id, Level, EffectiveDate, ExpirationDate 
     , Row_Number() Over ( Partition By Id 
           Order By EffectiveDate Desc, Coalesce(ExpirationDate,'99991231') Desc, Level Asc) As Num 
    From #Test 
    ) 
Select PkCol, Id, Level, EffectiveDate, ExpirationDate 
From Items 
Where Num = 1 

在您的样本输出,必须结合('000012-A12',2,'12/01/2005','01/01/2009')这不出现在您的原始数据中。

我正在使用在SQL Server 2005中添加的两个功能:公用表表达式和排名函数。公用表表达式Item就像就地查看或查询。排名功能Row_Number是真正的魔术发生的地方。顾名思义,它返回由Order By条款排序的数字的顺序列表。但是,它也会重新启动每个Id值的编号(即Partition By位)。通过筛选Num = 1,我将返回每个Id的“顶部”值。

+0

托马斯, 我刚刚得到了要求的澄清。下面 是场景 ID \t \t级生效日期\t到期日期 000012-12 \t \t 2 2005年12月1日\t NULL 000012-12 \t \t 1 2005年12月1日\t NULL 000012-12 \t \t 2 12/01/2005 \t 01/01/2009 000012-A12 \t \t 2 1994年10月1日2005年11月30日\t 000012-A12 \t \t 2 01/01/1999 \t 2005年11月30日 000012-A12 2001年9月1日\t二○○五年十一月三十○日 000012-A12 2005年12月1日\t 12/31/2007 我需要选择这将是对EXP日期的最新纪录..如果为空,那么选择一个。如果我们有多个记录具有相同的生效日期和到期日期,则选择第一级。我必须为tbl – user414610 2010-08-09 03:13:37

+0

@ sqllearner190中的所有Id做到这一点。您应该使用修改后的示例数据更新原始帖子。其他问题(db版本,auto_incrementing /标识列,用于比较的目标日期)呢? – Thomas 2010-08-09 03:20:22

+0

托马斯,我已经更新了这个要求。请帮忙,桌上也有身份证。 – user414610 2010-08-09 14:04:16