This can be done with CROSS JOIN , not sure how effective it is.
Sample data:
declare @Ranges table (SectionCategory varchar(10) not null,RangeName varchar(20) not null,LowerEnd int not null,UpperEnd int not null) insert into @Ranges (SectionCategory,RangeName,LowerEnd,UpperEnd) values ('Sanction','0-7 days',0,7), ('Sanction','8-15 days',8,15), ('Sanction','More than 15 days',16,99999), ('Disbursal','0-7 days',0,7), ('Disbursal','8-15 days',8,15), ('Disbursal','More than 15 days',16,99999) declare @Delays table (LoanNo int not null,SanctionDelay int not null,DisbursalDelay int not null) insert into @Delays (LoanNo,SanctionDelay,DisbursalDelay) values ( 247, 8,35), ( 661,18,37), (1235,12, 6), (1235, 8,15), (1241,28, 9), (1241,11, 9), (1283,22,20), (1283,28,41), (1523, 1,27), (1523, 6,28)
The request (should be executed in the same package as the sample data):
select r.SectionCategory, r.RangeName, SUM(CASE WHEN r.SectionCategory='Sanction' and d.SanctionDelay BETWEEN r.LowerEnd and r.UpperEnd then 1 WHEN r.SectionCategory='Disbursal' and d.DisbursalDelay BETWEEN r.LowerEnd and r.UpperEnd then 1 else 0 end) as Cnt from @Ranges r cross join @Delays d group by r.SectionCategory, r.RangeName order by SectionCategory,RangeName
Results:
SectionCategory RangeName Cnt
In terms of serviceability, it may be better to have a single delay column in the delay table and an additional column that defines the type of delay. At the moment, this looks like some form of attribute separation - in the Ranges table the type is represented as a column value ( Sanction , Disbursal , etc.), but in the delay table the same “type” is presented in the table metadata, in terms of different column names.
You say that “the number of stages in the life cycle of a loan is expected to increase,” and I expect that this crossroads (representing attributes as data in some tables and metadata in others) will increase the pain by writing worthy queries.