Você provavelmente gostaria de fazer conjuntos aninhados. Eles são um pouco complicados de configurar, mas tornam as consultas MUITO mais simples. Então, em vez da categoria pai, você terá duas colunas -
lft
e rgt
. Esquerda e direita são basicamente os limites de uma categoria, se o id de categoria de um item estiver entre esses valores, você saberá que é um filho dessa categoria. +----+---------------+-----+------+
| id | category name | lft | rgt |
+----+---------------+-----+------+
| 1 | cars | 1 | 24 |
+----+---------------+-----+------+
| 2 | bmw | 2 | 3 |
+----+---------------+-----+------+
| 5 | audi | 4 | 23 |
+----+---------------+-----+------+
| 6 | 100 | 5 | 6 |
+----+---------------+-----+------+
| 7 | 80 | 7 | 8 |
+----+---------------+-----+------+
| 8 | A4 | 9 | 22 |
+----+---------------+-----+------+
| 9 | TDI | 10 | 11 |
+----+---------------+-----+------+
| 10 | Quatro | 12 | 21 |
+----+---------------+-----+------+
| 11 | Black | 13 | 18 |
+----+---------------+-----+------+
| 12 | White | 19 | 20 |
+----+---------------+-----+------+
| 13 | 2 doors | 14 | 15 |
+----+---------------+-----+------+
| 14 | 5 doors | 16 | 17 |
+----+---------------+-----+------+
Então, para obter o número de itens na categoria carros, você pode fazer super simples assim:
SELECT categories.name, items.id, items.category_id, items.name
FROM categories
LEFT JOIN items
ON (items.category_id BETWEEN categories.lft AND categories.rgt)
WHERE categories.category_name = 'cars'
Obviamente, você pode apenas alterar o valor de
category_name
e obtenha os itens em QUALQUER categoria. Desculpe, por algum motivo a imagem girou quando eu a carreguei aqui, mas se você desenhar suas categorias como círculos e depois numerar as linhas, você pode ver qual deve ser o valor para esquerda e direita.
Eu só fiz carros porque imaginei que você poderia extrapolar para obter as outras categorias.
Então, se você escrever suas categorias assim:
Cars(BMW(), Audi(100(),80(),A4(TDI(),Quatro(Black(2dr(),5dr()), White())))
Então você pode rotular seus parênteses com números:
Cars[1]->(BMW[2]->()<-[3], Audi[4]->(100[5]->()<-[6],80[7]->()<-[8],A4[9]->(TDI[10]->()<-[11],Quatro[12]->(Black[13]->(2dr[14]->()<-[15], 5dr[16]->()<-[17])<-[18], White[19]->()<-[20])<-[21])<-[22])<-[23])<-[24]
Ou se você traçar como uma árvore, você pode rotulá-lo assim, onde você rotula o nó mais à esquerda com um número e apenas rotula o nó direito quando rotular todos os seus filhos: