通过SQL语句对数据进行排序
下表存储了个人id和日期的值:通过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
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语句让人印象深刻。这真的帮了我很大的忙,说明也很清楚。你给了我一个明确的方向。非常感谢。嗨,伙计,也谢谢你的帮助。你的逻辑可以很好地运作。但我更喜欢亚历克斯的答案。无论如何,非常感谢。