We are dancing around on the head of a pin here.
First and foremost, this is a cross-tab query, which is still easy enough to do. The only problem is that the cross-tab based on age in years would normally show those ages numerically.
SO... create a table that has records in it <1, "One">, <2, "Two">, <3, "Three"> etc for as many number-to-name cases as you wish. You could make a tuple that said <0,"Zero"> if that is important. Make the number the PK and let the name be a dependent variable (no key required).
Build a query that computes the age in years for each person and shows almost everything else you want total or count. But JOIN that query to the table of number-to-name translation. Call that JOIN query Layer1. Now build a Layer2 query that builds the crosstab of Layer1 including the text-name column as one of the attributes you are "crossing." You might have to diddle a bit with the order of items in the SELECT clause to get the names in the right place. You might also have to diddle with that a bit with a WHERE clause that only shows records with non-zero count or only shows records with the numeric part less than 21 or whatever.