I am looking for a solution to split date range if there is black/white list in place for a product. Currently my solution is using cross join to create sequence of dates between START_DATE and END_DATE with EXIST and NOT EXIST logic to deal with the black and white listing.
Data:
| PRODUCT | RETAILER | START_DATE | END_DATE | LIST_START_DATE | LIST_END_DATE | LIST |
|---|---|---|---|---|---|---|
| 1 | A | 2022-01-01 | 2022-01-30 | 2022-01-15 | 2022-01-28 | black |
| 2 | A | 2022-01-05 | 2022-01-30 | null | null | null |
| 3 | B | 2022-01-02 | 2022-01-30 | null | null | white |
| 4 | B | 2022-01-01 | 2022-01-29 | null | null | null |
Expected output:
| PRODUCT | RETAILER | START_DATE | END_DATE |
|---|---|---|---|
| 1 | A | 2022-01-01 | 2022-01-14 |
| 1 | A | 2022-01-29 | 2022-01-30 |
| 2 | A | 2022-01-05 | 2022-01-30 |
| 3 | B | 2022-01-02 | 2022-01-30 |
Rules:
- there can be either white or black list in place but never both
- if above happens then white list takes priority
- all products where list is null (no list present) are passed to the output unless white list is in place then products without list are excluded
- list_start_date and list_end_date can be null which means the product is excluded without time frame (forever)
- if black or white list date range is between start_date and end_date then records must be split to exclude/include these dates
In expected output product 1/retailer A is split into two records excluding dates between list_start_date and list_end_date because this range is black listed. Product 2/retailer A is included because it has no list and retailer has no white list in place. Product 3/retailer B is included because it is white listed without dates that means start_date and end_date are the effective dates. Product 4/retailer B is excluded because it has no list and retailer has white list in place.
Sample data:
with product(retailer,product,start_date,end_date) as (
select * from values
('A',1,'2022-01-01','2022-01-30'),
('A',2,'2022-01-05','2022-01-30'),
('B',3,'2022-01-02','2022-01-30'),
('B',4,'2022-01-01','2022-01-29')
), list(retailer, product, list, list_start_date, list_end_date) as (
select * from values
('A',1,'black','2022-01-15','2022-01-28'),
('B',3,'white',null, null)
), joined as (
select
product.product,
product.retailer,
product.start_date,
product.end_date,
list.list_start_date,
list.list_end_date,
list
from product
left join list
on list.retailer = product.retailer
and list.product = product.product
)
select *
from joined;
Thanks !