Home > OS >  Split Records by Effective Date
Split Records by Effective Date

Time:01-28

I'm working on an SQL Server database trying to split records based on effective dates and now on a stall on how to split them.

I have 2 tables: Subscription and Effective_Rates as follows:

Subscription

ID    |  Date_From   |  Date_To     |   Cost
------ -------------- -------------- ------------
1001  |  2020-01-01  |  2020-12-31  |  2000.00
1002  |  2020-05-01  |  2021-04-30  |  3500.00

Effective_Rates

ID    |  Effective_From   |  Rate  
------ ------------------- --------
1001  |  2020-01-01       |  10.0
1002  |  2020-08-01       |  12.0
1003  |  2021-01-01       |  15.0

I need to join these two tables and split the records by rate based on effective date and looking for the result as follows:

ID    |  Date_From   |  Date_To     |    Cost     | Rate
------ -------------- -------------- ------------- --------
1001  |  2020-01-01  |  2020-07-31  |  2000.00    | 10.0
1001  |  2020-08-01  |  2020-12-31  |  2000.00    | 12.0
1002  |  2020-05-01  |  2020-07-31  |  3500.00    | 10.0
1002  |  2020-08-01  |  2020-12-31  |  3500.00    | 12.0
1002  |  2021-01-01  |  2021-04-30  |  3500.00    | 15.0

Again, appreciate your help

CodePudding user response:

WITH SUBSCRIPTION(ID,DATE_FROM,DATE_TO,COST) AS
(
  SELECT 1001  ,  '2020-01-01'  ,  '2020-12-31'  ,  2000.00 UNION ALL
  SELECT 1002  ,  '2020-05-01'  ,  '2021-04-31'  ,  3500.00
),
Effective_Rates(ID , Effective_From, Rate )AS
(
  SELECT 1001  ,  '2020-01-01'       ,  10.0 UNION ALL
  SELECT 1002  ,  '2020-08-01'       ,  12.0 UNION ALL
  SELECT 1003  ,  '2021-01-01'       ,  15.0
)

SELECT S.ID,S.DATE_FROM,S.DATE_TO,S.COST,X.Rate,X.Effective_From
 FROM SUBSCRIPTION AS S
CROSS APPLY
 (
   SELECT E.RATE,E.Effective_From
   FROM Effective_Rates AS E
   WHERE E.Effective_From BETWEEN S.DATE_FROM AND S.DATE_TO
)X
ORDER BY S.ID;

I am afraid it is not suitable completely, but hope can be useful

CodePudding user response:

Intervals a and b intersection condition is a.start<=b.end and b.start<=a.end. So intervals of interest can be found with the query

with eri as(
  select ID, Effective_From, Rate
   , dateadd(dd, -1, lead(Effective_From) over(order by Effective_From) ) eff_till
  from Effective_Rates
)   
SELECT S.ID 
   , case when S.DATE_FROM <= eri.Effective_From then eri.Effective_From else S.DATE_FROM end d_from
   , case when S.DATE_TO <= eri.eff_till or eri.eff_till is null then S.DATE_TO else eri.eff_till end d_to
   , S.COST, eri.Rate, eri.Effective_From
FROM SUBSCRIPTION AS S
JOIN eri on eri.Effective_From <=  S.DATE_TO and (s.DATE_FROM < eri.eff_till or eri.eff_till is null)
ORDER BY S.ID, d_from;

db<>fiddle

  •  Tags:  
  • Related