I'm adding another solution since a completely different approach would be to squeeze the logic into a single statement. If I didn't make too many mistakes, it should look something like
with a as (
select campaign_id,
Campaign_desc,
CONVERT(VARCHAR(19),
max(Campaign_start_date), 120) as 'Campaign_start_date',
cell_id,
filename as 'cell_name',
'' as 'list_name',
'' as 'list_id',
'' as 'source_code'
from (SELECT e.email_source as'campaign_id',
e.campaign as 'Campaign_desc',
e.date_time as 'Campaign_start_date',
e.cell_id,
e.filename
FROM ( select distinct email_source, campaign, date_time, cell_id, filename
from master
where campaign in (select distinct campaign
from ReportingAcxiom)
) e
INNER JOIN ReportingAcxiom ON e.campaign = ReportingAcxiom.campaign
and e.email_source = ReportingAcxiom.campaign_id
and e.cell_id = ReportingAcxiom.cell_id) ecamp
group by campaign_id, Campaign_desc, cell_id, filename
)
select campaign_id,
Campaign_desc,
CONVERT(VARCHAR(19),
max(Campaign_start_date), 120) as 'Campaign_start_date',
CONVERT(VARCHAR(19),
dateadd(m, 1, cast(Campaign_start_date as datetime)), 120) as 'Campaign_end_date',
cell_id,
cell_name,
'' as 'list_name',
'' as 'list_id',
'' as 'source_code'
from a
group by campaign_id, Campaign_desc, Campaign_start_date, cell_id, cell_name;
If you want to test you can still leave the three first indexes in the database but you don't need the temp tables or temp table index anymore