From what you are describing, I would have a separate aggregate table to query directly from that has those "roll-up" stats you want. How frequent is the "Person" table getting added to / changed. If you are only storing a person's "Age", what is the basis of the age if no date, and you add the person again in future they would have multiple records... such that
At age X, so many people were married (or not) and had this level of education.
At age Y, so many people... etc..
I would create a summary table, something like
create table AgeStat (
age int,
married int,
single int,
divorced int,
HighSchool int,
Associates int,
Bachelors int,
Masters int,
Doctorate int )
Then, add a trigger to the person table such that during insert (or inclusive of update/delete as needed), the new record just adds 1 to each respective count applicable.
Then, for your web app, it would be instantaneous to grab one record from this summary table where age = 27 and you have ALL your classification stats.
However, if you distinctly wanted to know how many Married with Masters degree, you would have to roll back to master person list.
Alternatively, you could do a similar pre-aggregation but down a level of granularity something like
create table AgeStat (
age int,
maritalstat int, -- but I would actually use an enumerated value for marital status
educationlevel int, -- and education level vs a hard description of each.
peoplecount int )
and likewise have a trigger that updates the count based on the two combination elements per age. Then, if you wanted the total "Married", you can sum(peoplecount) for age = 27 and maritalstat=(enumerator for "married" value)
Good luck, and hope it helps alternative solution for you.