There is a Categories table:
Categories----------
iid (I4) - Primary
category (C30)
It holds all the possible category names (at any level)
Then a Category Groups table:
CategoryGroups--------------
iid (I4) - Primary
group_id (I4)
fk_categoryid (I4)
level (I4)
This table defines all the possible combinations (groupings).
A sample of the data might look like:
Category
--------
iid category
1, Automobiles
2, GM
3, Ford
4, Daimler-Chrysler
5, Computers
6, Compaq
7, Dell
CategoryGroups
--------------
iid, group_id, fk_categoryid, level
1, 1, 1, (auto) 1
2, 1, 2, (GM) 2
3, 2, 1, (auto) 1
4, 2, 3, (Ford) 2
5, 3, 1, (auto) 1
6, 3, 4, (D-C) 2
7, 4, 5, (Computers) 1
8, 4, 6, (Compaq) 2
9, 5, 5, (Computers) 1
10, 5, 7, (Dell) 2
All entries that are "Level 1" are primary categories, level 2, 3, etc are
subcategories. So the grouping defined by the above data would look like:
Automobiles
- GM
- Ford
- Daimler-Chrysler
Computers
- Compaq
- Dell
It's easy enough to add more levels to any of the above categories. For
instance, if we wanted to add different divisions for GM, we could add:
Categories
----------
iid category
8, Chevy
9, Pontiac
CategoryGroups
--------------
iid, group_id, fk_categoryid, level
8, 6, 1, (Auto) 1
9, 6, 2, (GM) 2
10, 6, 8, (Chevy) 3
11, 7, 1, (Auto) 1
12, 7, 2, (GM) 2
13, 7, 9, (Pontiac) 3
Each CategoryGroup defines a full path from Primary category to ending
subcategory.
* Primary Categories
SELECT (blah blah) WHERE CategoryGroups.level == 1