[英]Date calculation sql (oracle)
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的開始日期以保持連續性)
先謝謝哈利
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語句比較棘手。
您可以使用lag
函數來引用上一行中的值(定義'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小提琴 )。
首先when
該條款case
被處理的“第一”行,最早起始日期; 由於沒有前一行, lag
將為null
。
然后,您可以過濾結果以獲取start_date
和adj_start_date
不匹配的結果。 ( 另一個SQL小提琴 )。
您可以在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小提琴 )。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.