通过SQL语句对数据进行排序

通过SQL语句对数据进行排序,sql,oracle-sqldeveloper,Sql,Oracle Sqldeveloper,下表存储了个人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

下表存储了个人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行的生效日期是1988年7月9日,那么我对第1行的终止生效日期应该是它的前一天(1988年7月8日)。虽然我的“最大生效日期”的结束生效日期始终为9999年12月31日。

但是,您必须拥有生效日期与下一个生效日期之间的配对

 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')
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)
选择P1.生效日期,P2.生效日期
从个人id P1,个人id P2,其中P1.effect_Date
我想加入一定会更好

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

希望这对您有所帮助。运行查询并检查结果

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中使用相同的值。

您可以使用
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          

你对end efeectiveDate的逻辑是什么?你能告诉我们你想在这里做什么吗?嗨,我刚刚编辑了我的问题,请先看一下。对不起,我没有把问题说清楚。嗨,老兄,我刚刚编辑了我的问题。请先看一看。(^.^)谢谢。嗨,katria,如果没有提供最终生效日期,那么它必须由SQL中的逻辑控制,而SQL中的逻辑总是在下一个生效日期的前一天?嗨,伙计,你刚才写的SQL语句让人印象深刻。这真的帮了我很大的忙,说明也很清楚。你给了我一个明确的方向。非常感谢。嗨,伙计,也谢谢你的帮助。你的逻辑可以很好地运作。但我更喜欢亚历克斯的答案。无论如何,非常感谢。