Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
114 views
in Technique[技术] by (71.8m points)

sql - Merge data depending on object and no gaps in dates

I have got in the DB data like you can see below (additional info about dates: date in valid_from is included, date in valid_to is excluded)

obj_number obj_related valid_from valid_to
AA BB 01.01.2018 01.01.2019
AA BB 01.01.2019 31.03.2019
AA BB 31.03.2019
AA CC 01.01.2020 30.06.2020
AA CC 02.07.2020 31.10.2020
AA CC 31.10.2020 31.12.2020
AA DD 01.01.2018 30.11.2020
AA DD 30.11.2020 31.12.2020
question from:https://stackoverflow.com/questions/65940272/merge-data-depending-on-object-and-no-gaps-in-dates

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is a different solution, which should work in Oracle 10.1 and higher - using the Tabibitosan method. The problem is slightly complicated by the use of NULL to mark an indefinite valid_to date; in particular, the definition of valid_to in the outer query can't simply be max(valid_to) within each group, since that would produce the wrong answer when valid_to may be null.

Other than that, the computation that produces the grp column in the subquery is the main idea: it produces a different date for each "island" in the "gaps and islands" structure of the input data. This is a less known use of the Tabibitosan method; it makes this kind of query as efficient as possible since it requires only one level of analytic functions.

/*
with
  sample_data (...) as (...)
*/
select obj_number, obj_related, min(valid_from) as valid_from,
       max(valid_to) keep (dense_rank last order by valid_from) as valid_to
from   (
         select sd.*,
                nvl(valid_to, date '9999-12-31') - 
                  sum(nvl(valid_to, date '9999-12-31') - valid_from)
                      over (partition by obj_number, obj_related 
                            order     by valid_from) as grp
         from   sample_data sd
       )
group  by obj_number, obj_related, grp
order  by obj_number, obj_related, valid_from
;

The best way to try to understand how the Tabibitosan method works (in this case) is to run the subquery separately and to see what it produces.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...