1

下面是一个存储personal_id和日期值的表:

  Person_ID    Effective_Date     End Effective_Date
  1)6335         24/02/1999
  2)6335         09/07/1998
  3)6335         26/06/1998

并且输出表应该像

  Person_ID    Effective_Date     End Effective_Date
  1)6335         24/02/1999           31/12/9999
  2)6335         09/07/1998           23/02/1999
  3)6335         26/06/1998           08/07/1998

如果我使用 java 代码更新它,逻辑将非常简单。但是可以通过使用SQL语句来完成吗?我需要有人为我提供这样做的逻辑。我当前的结束生效日期将始终是下一个生效日期的前一天。假设我对第 2 行的生效日期是 09/07/1988,那么我对第 1 行的结束生效日期应该是前一天(08/07/1988)。虽然我的最大生效日期的结束生效日期将始终是 31/12/9999。

4

4 回答 4

1

希望这可以帮助你。运行查询并检查结果。

DECLARE @tbl table (ID int, D1 DATETIME, D2 DATETIME)

INSERT INTO @tbl
select 1,'2/28/2013','2/28/2013'
union all
select 2,'3/2/2013','3/2/2013'
union all
select 3,'4/2/2013','4/2/2013'
union all
select 4,'4/6/2013','4/6/2013'
union all
select 5,'5/21/2013','5/21/2013'
union all
select 6,'6/10/2013','6/10/2013'

SELECT * FROM @tbl

UPDATE t1
SET t1.D2= DATEADD(DAY, -1, t2.D2)
FROM @tbl t1
     CROSS JOIN @tbl t2
WHERE t2.D1=(SELECT min(D1)
               FROM @tbl t
               WHERE D1>t1.D1)


SELECT * FROM @tbl

UPDATE @tbl
SET D2 = '12/31/9999'
WHERE D2 = (SELECT TOP 1 D2 FROM @tbl ORDER BY D2 DESC)

SELECT * FROM @tbl

这可能不是最有效的情况,但它假定最初您在 D1 和 D2 中的值相同。

于 2013-07-04T07:48:46.037 回答
1

您可以使用该lead函数查看下一行并获取其生效日期:

select person_id, effective_date,
  lead(effective_date)
    over (partition by person_id order by effective_date) as lead_date
from t42;

 PERSON_ID EFFECTIVE_DATE LEAD_DATE
---------- -------------- ---------
      6335 26-JUN-98      09-JUL-98 
      6335 09-JUL-98      24-FEB-99 
      6335 24-FEB-99

然后,您可以使用它来执行更新。该merge命令使这很容易:

merge into t42
using (
  select person_id, effective_date,
    lead(effective_date)
      over (partition by person_id order by effective_date) as lead_date
  from t42
) t
on (t42.person_id = t.person_id and t42.effective_date = t.effective_date)
when matched then
update set t42.end_effective_date =
  case
    when t.lead_date is null then date '9999-12-31'
    else t.lead_date - 1
  end;

3 rows merged.

select * from t42;

 PERSON_ID EFFECTIVE_DATE END_EFFECTIVE_DATE
---------- -------------- ------------------
      6335 26-JUN-98      08-JUL-98          
      6335 09-JUL-98      23-FEB-99          
      6335 24-FEB-99      31-DEC-99          

using子句具有上面的代码段,从前一行获取日期。该on子句将此与您的原始表相匹配,并且对于匹配的行,将结束生效日期更新为潜在客户生效日期的前一天,或者如果没有潜在客户值(对于最近的“当前”行),则使用固定日期从 1999 年开始。

您的问题涉及更新,但如果您只想将结束日期作为结果集中的计算列,则要简单得多:

select person_id, effective_date,
  case when lead_date is null then date '9999-12-31'
    else lead_date - 1 end as end_effective_date
from (
  select person_id, effective_date,
    lead(effective_date)
      over (partition by person_id order by effective_date) as lead_date
  from t42
);

 PERSON_ID EFFECTIVE_DATE END_EFFECTIVE_DATE
---------- -------------- ------------------
      6335 26-JUN-98      08-JUL-98          
      6335 09-JUL-98      23-FEB-99          
      6335 24-FEB-99      31-DEC-99          
于 2013-07-04T07:49:03.217 回答
0

但是您必须将 Effective_date 与下一个 Effective_date 配对

SELECT P1.Effective_Date, P2.Effective_Date 
FROM personal_id P1, personal_id P2 where P1.Effective_Date < P2.Effective_Date 
GROUP BY P1.Effective_Date
HAVING P2.Effective_Date = MIN(P2.Effective_Date)

我认为加入一定会更好

之后:您在结束生效日期进行更新。

于 2013-07-04T07:21:14.257 回答
0
 UPDATE personal_id SET [End Effective_Date] = To_date('31/12/9999', 'dd/mm/yyyy') 
 WHERE Person_ID = 6335 AND Effective_Date = To_date('24/02/1999', 'dd/mm/yyyy')
于 2013-07-04T05:57:44.180 回答