Row No. Start Date End Date
1 28/11/2012 28/11/2012
2 28/11/2012 6/12/2012
3 6/12/2012 6/12/2012
4 22/01/2013 23/01/2013
5 23/01/2013
我根据以上示例数据进行了两次查询: -
SQL将记录带到日期没有连续性的地方(例如,rrecord 3结束 12/12/2012,但记录4于2013年1月22日开始)
调整日期没有连续性的日期(例如,更新记录的开始日期 4至6/12/12使连续性
提前致谢 哈利
答案 0 :(得分:1)
SELECT语句很简单:
select * from your_table t1
where t1.end_date is not null
and not exists
( select null from your_table t2
where t2.start_date = t1.end_date
and t2.row_no != t1.row_no )
子查询阻止记录3满足自身的限定条件。这可能不是完整的解决方案。如果您有多个具有相同开始日期和结束日期的记录,那么您最终可能无法识别某些记录。在这种情况下,ROW_NO的可靠性很重要。
如果你可以保证对于任何给定的记录对,较高的ROW_NO总是表示按时间顺序排列的记录,那么修复很简单:
where t2.start_date = t1.end_date
and t2.row_no > t1.row_no )
在某些情况下,这种担保可能无法实现;这取决于如何分配ROW_NO。但是这里已经有很多假设,除非你提供进一步的细节,否则我不打算解决它们。
UPDATE语句比较棘手。
答案 1 :(得分:1)
您可以使用lag
function引用上一行中的值(定义'previous'在查询中的含义;我假设您的'行号'是伪列,而不是您可以订购的实际列,并且您希望它们以开始日期顺序排列):
select start_date, end_date,
case
when lag_end_date is null then start_date
when lag_end_date = start_date then start_date
else lag_end_date
end as adj_start_date
from (
select start_date, end_date,
lag(end_date) over (order by start_date, end_date) as lag_end_date
from <your_table>
)
(SQL Fiddle)。
when
的第一个case
子句正在处理“第一”行,其中包含最早的开始日期;由于前一行lag
不会是null
。
然后,您可以过滤结果,以获取start_date
和adj_start_date
不匹配的结果。 (Another SQL Fiddle)。
您可以在merge
中使用相同类型的构造进行更新:
merge into <your table>
using (
select r_id, start_date, end_date,
case when lag_end_date is null then null
when lag_end_date = start_date then null
else lag_end_date
end as adj_start_date
from (
select rowid as r_id, start_date, end_date,
lag(end_date) over (order by start_date, end_date) as lag_end_date
from t42
)
) t
on (your_table>.rowid = t.r_id and t.adj_start_date is not null)
when matched then
update set <your table>.start_date = t.adj_start_date;
(SQL Fiddle)。