GROUPING SETS query with many-to-many relationships
Your problem query:
-- this query shows how the join leads to wrong aggregate 
-- results, as it obviously duplicates rows
-- 'y' appears only once in the table, but is counted twice here
select grouping(b),b,count(*)
from demo 
left join demo_stuff on id = demo_id 
group by grouping sets ((b),());
Result:
grouping | b    | count
-------: | :--- | ----:
       0 | z    |     2
       0 | y    |     2
       1 | null |     4

Your comment is slightly inaccurate. The &quot;table&quot; is the derived table after joining demo and demo_stuff, and 'y' appears twice there. Either you want count(DISTINCT demo.id) in the result, or count(*). Those counts are different by nature and should go into separate result columns:

SELECT grouping(b), b
     , count(DISTINCT d.id) AS ct_distinct_demos
     , count(*)             AS ct_rows  -- your org count
FROM   demo d
LEFT   JOIN demo_stuff s ON d.id = s.demo_id 
GROUP  BY GROUPING SETS ((b), ())
ORDER  BY 1;
Result:
grouping | b    | ct_distinct_demos | ct_rows
-------: | :--- | ----------------: | ------:
       0 | y    |                 1 |       2
       0 | z    |                 2 |       2
       1 | null |                 3 |       4

db&lt;&gt;fiddle here
You'll have to define precisely what to count for the correct solution. Might result in count(d.b) or count(*) or count (DISTINCT d.b) ...