Performing SELECT on EACH ROW in CTE or Nested QUERY?
Let me know if this helps.  This is using MSSQL (T-SQL) syntax so you might have to adjust it for postgres, but, using a temp table called #tree, containing the two columns id and parent and populated as your example is with

SELECT 1, 0
UNION 
SELECT 2, 1
UNION 
SELECT 3, 1
UNION
SELECT 4, 2
UNION 
SELECT 5, 2
UNION 
SELECT 6, 4
UNION
SELECT 7, 6
UNION 
SELECT 8, 6:

with cte as
(
    select id as currentnode, id as root
    from #tree
    union all
    select t.id as currentnode, cte.root 
    from #tree t join cte on t.parent = cte.currentnode
)
select *
from cte
order by root


The above recursive CTE will yield all nodes reachable starting from some root.  You can do:

SELECT root, count(*)
from cte
group by root


The count(*) query should yield,

root   |  count
----------------
  1    |    8
  2    |    6
  3    |    1
  4    |    4
  5    |    1
  6    |    3
  7    |    1
  8    |    1


You could then subtract 1 from each of those to get the result you were hinting at.  Is this what you were looking for?  Even if not, I feel like a recursive CTE can probably help with what you need.