SQL query on percentage share of different groups in total
CTEs

A CTE is an optimization fence. You'll want to try to avoid it and at the least convert it into a subquery.

Casting

Do an explicit cast instead of an implicit cast:

0.00 + COUNT(*)


becomes

count(*)::real


Between

Rather than writing

  loan_loan.created_at &gt; '2019-08-15' and 
  loan_loan.created_at &lt; '2019-09-05'


write

  loan_loan.created_at between '2019-08-15' and '2019-09-05'


Joining

More broadly: are you sure this is doing the right thing? You aren't selecting type from your CTE to join to your upper query's loan_loan.type. Given the lack of this join, I fail to see how your total column will be reliably matched to your upper rows.