If I understand correctly you want to have the rollup result value before the values rolled up as opposed to the SQL standard.
The closest I could come up with is the following:
SELECT
isnull(CAST(storenbr AS VARCHAR(50)),isnull(stores.districtname,stores.companyname)) AS Grp
,SUM(Mature) as Mature
,Sum(Cooking) as Cooking
,Sum(Exercise) as Exercise
,Sum(Math) as Math
,Sum(AudioBooks) as AudioBooks
,Sum(Childrens) as Childrens
,Sum(Spanish) as Spanish
from booksales sales
inner join bookstores stores on stores.storeid = sales.storeid
INNER JOIN
(SELECT [COMPANYNAME],[DISTRICTNAME],MIN([STORENBR]) AS MIN_STORENBR
FROM bookstores
GROUP BY [COMPANYNAME],[DISTRICTNAME]
) stores2 ON stores2.[COMPANYNAME] = stores.[COMPANYNAME]
AND stores2.[DISTRICTNAME] = stores.[DISTRICTNAME]
group BY stores.companyname
, stores.districtname
,MIN_STORENBR
, STORES.STORENBR
WITH rollup
HAVING
ISNULL(MIN_STORENBR,stores.storenbr) IS NOT NULL
OR stores.companyname IS NOT NULL
AND stores.districtname IS NULL
ORDER BY
isnull(MIN_STORENBR,' ' + stores.companyname),
isnull(storenbr,' ' + isnull(stores.districtname,' '+ stores.companyname))
The result set will display the rollup values first and the district order as requested.
However, your requirement to sort by district with the smallest shop number first is really strange (and it requires an additional join just for display order)...
Another question: What is the specific reason to do this with SQL anyway? Usually, rollup and sorting (especially nonstandard) can and should be done by the application...
Edit: wrong SQL posted before ...