Delete relations efficiency in PostgreSQL
You can do all in a single data modifying CTE

with deleted_impressions as (
  delete from impressions i1
  where exists (select * 
                from impressions i2
                where i2.id &gt; i1.id
                  and i2.created_at = i1.created_at)
  returning id
), delete_reg_impressions as (
  delete from regional_impressions
  where impression_id in (select id 
                        from deleted_impressions)
) 
delete from demographic_distribution
where impression_id in (select id 
                        from deleted_impressions);


First the duplicates from impressions are removed and all IDs that are returned from that query are then used to delete the corresponding rows in demographic_distribution as this is done in a single (atomic) statement the foreign keys are still valid.