Skip to content
Advertisement

joining temporal tables in oracle

I am looking for better solutions to a fairly generic problem with temporal tables.

say we have

and a series of similar tables table_b, table_c, …

the actual system is an HR system that tracks persons, contracts, assignments, salaries, … all they are all dated in the way described above.

I need to join such tables (e.g. imagine getting all rows with the same some_value) and return the period for which such join is valid (that is all the rows overlap over such period).

with two tables it is easy (ignore NULL values for the time being)

this become quadratically harder with more tables, because with three table (A, B, C) you need to check the overlap between A and B, B and C, C and A. with N tables this grows as N^2.

so I have written a pl/sql pipelined function (call it dated_join) that given two intervals it returns one row with the overlapping period or nothing if it doesn’t overlap

so I can have for three tables

this scales linearly to N values, because each period is joined only with the previous one and it carries forward the overlapping period.

question: is it possible to make this strategy work with OUTER JOINs? I cannot find any half-decent solution.

is there anything in the SQL:2011 temporal extensions that would help with this?

thanks for your help

Advertisement

Answer

If you want to join multiple table so that they all overlap the same period then you can use GREATEST and LEAST:

Which, for the sample data:

Outputs:

T1_FROM   | T2_FROM   | T3_FROM   | T4_FROM   | T1_TO     | T2_TO     | T3_TO     | T4_TO    
:-------- | :-------- | :-------- | :-------- | :-------- | :-------- | :-------- | :--------
15-MAR-20 | 16-MAR-20 | 15-MAR-20 | 16-MAR-20 | 18-MAR-20 | 18-MAR-20 | 17-MAR-20 | 19-MAR-20
10-FEB-20 | 09-FEB-20 | 08-FEB-20 | 08-FEB-20 | 15-FEB-20 | 16-FEB-20 | 17-FEB-20 | 17-FEB-20
01-JAN-20 | 05-JAN-20 | 09-JAN-20 | 02-JAN-20 | 10-JAN-20 | 15-JAN-20 | 16-JAN-20 | 12-JAN-20

and, if you want it so that there is an overlap with any part of the ranges, then swap the GREATEST and LEAST:

Which outputs:

T1_FROM   | T2_FROM   | T3_FROM   | T4_FROM   | T1_TO     | T2_TO     | T3_TO     | T4_TO    
:-------- | :-------- | :-------- | :-------- | :-------- | :-------- | :-------- | :--------
15-MAR-20 | 16-MAR-20 | 15-MAR-20 | 16-MAR-20 | 18-MAR-20 | 18-MAR-20 | 17-MAR-20 | 19-MAR-20
10-FEB-20 | 09-FEB-20 | 08-FEB-20 | 08-FEB-20 | 15-FEB-20 | 16-FEB-20 | 17-FEB-20 | 17-FEB-20
01-JAN-20 | 05-JAN-20 | 01-JAN-20 | 02-JAN-20 | 10-JAN-20 | 15-JAN-20 | 02-JAN-20 | 12-JAN-20
01-JAN-20 | 05-JAN-20 | 09-JAN-20 | 02-JAN-20 | 10-JAN-20 | 15-JAN-20 | 16-JAN-20 | 12-JAN-20

db<>fiddle here

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement