As you are trying to do this in pl/sql, you should be able to something based on the following.
DECLARE
v_product VARCHAR2(100);
v_total_count NUMBER := 0;
CURSOR product_cursor IS
SELECT DISTINCT product_name
FROM Product
ORDER BY product_name;
CURSOR category_cursor(p_product VARCHAR2) IS
SELECT c.cat_name, COUNT(*) as count
FROM Product p
JOIN Category c ON p.category_id = c.cat_id
WHERE p.product_name = p_product
GROUP BY c.cat_name
ORDER BY c.cat_name;
BEGIN
FOR product_rec IN product_cursor LOOP
v_product := product_rec.product_name;
v_total_count := 0;
FOR category_rec IN category_cursor(v_product) LOOP
IF v_total_count = 0 THEN
DBMS_OUTPUT.PUT_LINE(RPAD(v_product, 8) || ' ' ||
RPAD(category_rec.cat_name, 9) || ' ' ||
LPAD(TO_CHAR(category_rec.count), 5));
ELSE
DBMS_OUTPUT.PUT_LINE(RPAD(' ', 8) || ' ' ||
RPAD(category_rec.cat_name, 9) || ' ' ||
LPAD(TO_CHAR(category_rec.count), 5));
END IF;
v_total_count := v_total_count + category_rec.count;
END LOOP;
DBMS_OUTPUT.PUT_LINE(RPAD(' ', 24) || LPAD(TO_CHAR(v_total_count), 11));
END LOOP;
END;
/
It’s not an ideal solution because it ignores the power of set based operations but it fulfils what you’re asking for,