WITH CTE_Dates (cte_date, country_name) AS ( SELECT cast(TRUNC(@OldestFromDate , 'MONTH') as date), {Country}.[Description] FROM dual, {Country} WHERE {Country}.[Id] in (@CountryId) UNION ALL SELECT cast(ADD_MONTHS(TRUNC(cte_date, 'MONTH'), 1) as date), country_name FROM CTE_Dates WHERE ADD_MONTHS(TRUNC(cte_date, 'MONTH'), 1) <= @NewestToDate ), country_counts (num, description, moyear) as ( SELECT Count(*) num, {Country}.[Description], to_char({Applicant}.[StartDate], 'YYYY-MM-"01"') FROM {Applicant} JOIN {Country} on {Country}.[Id] = {Applicant}.[CountryId] JOIN {ApplicantPosition} on {ApplicantPosition}.[ApplicantId]={Applicant}.[Id] JOIN {Position} on {Position}.[Id] = {ApplicantPosition}.[PositionId] WHERE ( (@ApplicationSubmitted = 1 and ({Applicant}.[StartDate] BETWEEN @FromDate AND @ToDate and {Applicant}.[SubmitDate] <> to_date('01-01-1900','DD-MM-YYYY')) ) or (@ApplicationInProcess = 1 and ({Applicant}.[StartDate] BETWEEN @InProcessFromDate AND @InProcessToDate and {Applicant}.[SubmitDate] = to_date('01-01-1900','DD-MM-YYYY')) )) and {Applicant}.[CountryId] IN (@CountryId) and {Position}.[Id] IN (@ProfessionId) group by to_char({Applicant}.[StartDate], 'YYYY-MM-"01"'),{Country}.[Description] ORDER BY to_char({Applicant}.[StartDate], 'YYYY-MM-"01"') asc) SELECT to_char(cte_date, 'YYYY-MM-DD'), country_name, COALESCE(country_counts.num, 0) FROM CTE_Dates left join country_counts on moyear=to_char(cte_date, 'YYYY-MM-DD') and description = country_name WHERE (cte_date BETWEEN @FromDate AND @ToDate OR cte_date BETWEEN @InProcessFromDate AND @InProcessToDate ) ORDER BY CTE_Date, country_name asc