Hi,
I need a sql query to calculate batch_number based on the dates. For the same name and country we need to show same batch number up to 12 months. For next batch we have to start from that date and consider upto 12 months as next batch.
Here is the sample data. I have manually added batch number in below query but we have to calculate them dynamically using sql.
create table test_batches as
select 'a' name , 'australia' country,to_date('01-Jan-2018') batch_Date, 'B1' batch_number from dual
union all
select 'a' name , 'australia' country,to_date('01-Jul-2018'), 'B1' batch_number from dual
union all
select 'a' name , 'australia' country,to_date('01-Nov-2018'), 'B1' batch_number from dual
union all
select 'a' name , 'australia' country,to_date('31-Dec-2018'), 'B1' batch_number from dual
union all
select 'a' name , 'australia' country,to_date('10-Mar-2019'), 'B2' batch_number from dual
union all
select 'a' name , 'australia' country,to_date('01-Oct-2019'), 'B2' batch_number from dual
union all
select 'a' name , 'australia' country,to_date('01-Jan-2020') , 'B2' batch_number from dual
union all
select 'a' name , 'australia' country,to_date('09-Mar-2020'), 'B2' batch_number from dual
union all
select 'a' name , 'australia' country,to_date('10-Mar-2020'), 'B3' batch_number from dual
union all
select 'a' name , 'australia' country,to_date('01-Aug-2020'), 'B3' batch_number from dual
union all
select 'b' name , 'australia' country,to_date('01-Jan-2018') , 'B1' batch_number from dual
For user A
batch1 start from '1-Jan-2018' and for upto 12 months we have to show data as B1.
batch2 starts from '10-Mar-2019' as it is first date beyond 12 months, this batch continue for the next 12 months upto '09-Mar-2020'
batch3 will start from '10-Mar-2020'
For user B
we have to follow the same approach as above.
tried using function but it has performance issues, so need to do it in a query. Please help.
I'm confused. Are the dates you've shown what's in your real data? Or do you just have the first date for each batch, then need to generate everything for the next 12 months?
Anyway, the basic idea is:
- Have a table of dates you want to display; you can generate this on the fly or use a real table. I've restricted to month starts to keep the data set small
- Get the first and last date you want to display for each name, batch, and country. If you only have one the initial row, just add 12 months and subtract a day. If you've got dates in between you'll need to do something more exotic
- Join these ranges to the dates that fall beteen the start and end
e.g.:
with dates as (
select add_months ( date'2018-01-01', level - 1 ) mth
from dual
connect by level <= 36
), ranges as (
select name, country, batch_number,
min ( batch_date ) st_dt,
add_months ( min ( batch_date ), 12 ) - 1 en_dt
from test_batches
group by name, country, batch_number
)
select mth, name, country, batch_number
from dates
join ranges
on mth between st_dt and en_dt
order by name, mth;
MTH NAME COUNTRY BATCH_NUMBER
01-JAN-2018 a australia B1
01-FEB-2018 a australia B1
01-MAR-2018 a australia B1
01-APR-2018 a australia B1
01-MAY-2018 a australia B1
01-JUN-2018 a australia B1
01-JUL-2018 a australia B1
01-AUG-2018 a australia B1
01-SEP-2018 a australia B1
01-OCT-2018 a australia B1
01-NOV-2018 a australia B1
01-DEC-2018 a australia B1
01-APR-2019 a australia B2
01-MAY-2019 a australia B2
01-JUN-2019 a australia B2
01-JUL-2019 a australia B2
01-AUG-2019 a australia B2
01-SEP-2019 a australia B2
01-OCT-2019 a australia B2
01-NOV-2019 a australia B2
01-DEC-2019 a australia B2
01-JAN-2020 a australia B2
01-FEB-2020 a australia B2
01-MAR-2020 a australia B2
01-APR-2020 a australia B3
01-MAY-2020 a australia B3
01-JUN-2020 a australia B3
01-JUL-2020 a australia B3
01-AUG-2020 a australia B3
01-SEP-2020 a australia B3
01-OCT-2020 a australia B3
01-NOV-2020 a australia B3
01-DEC-2020 a australia B3
01-JAN-2018 b australia B1
01-FEB-2018 b australia B1
01-MAR-2018 b australia B1
01-APR-2018 b australia B1
01-MAY-2018 b australia B1
01-JUN-2018 b australia B1
01-JUL-2018 b australia B1
01-AUG-2018 b australia B1
01-SEP-2018 b australia B1
01-OCT-2018 b australia B1
01-NOV-2018 b australia B1
01-DEC-2018 b australia B1