postgres subquery uses ungrouped column
You can do that using a filtered aggregate, no need for subselects at all

to_char(100 * (count(*) filter (where ipam_addresses.host_id = 0)) / count(*)::numeric, '999D99%') v 


The cast ::numeric is needed to avoid integer division