There are two things that I prefer to do in a different way:
The first is your use of ISNULL(FieldName, 'ZTotal') -- I prefer to use a case statement
CASE GROUPING(FieldName) WHEN 0 THEN FieldName ELSE 'Total' END -- this protects against a NULL value being mistaken for a total
The second is your order by using 'ZTotal' to make it go to the bottom -- I prefer to once again use the GROUPING() function
ORDER BY GROUPING(FieldName) -- which puts all the non-subtotals at the top since GROUPING() = 0 and the subtotals at the bottom where GROUPING() = 1
This also allows you to easily reverse the order and put the totals at the top by adding DESC -- and you don't have to worry about the dreaded 'Zygote' which sorts lower than 'ZTotal'
Another suggestion that I saw was using a Cube to get some the rollups to work in both directions -- you can always use a HAVING at the bottom to filter out any groups that you don't want, but you have to be very careful with the GROUP BY order or you'll lose more groupings
Examples:
HAVING GROUPING(FieldName) = 0 will not show any sub totals for that grouping
HAVING GROUPING(FieldWithID) = GROUPING(FieldWithValue) will not show any extra grouping for fields like StateID and StateValue