Dodaj kolumnę do kategorii, która podaje główną kategorię, w której znajduje się każda kategoria (z głównymi kategoriami podającymi siebie). A więc:
cat_id | main_cat_id | title
-------+-------------+---------
01 | 01 | Science
0101 | 01 | Medicine
02 | 02 | Sport
Wybierz z tego na cat_id =main_cat_id, aby znaleźć główne kategorie; dołącz z powrotem do siebie na left.cat_id =right.main_cat_id, aby znaleźć kategorie podrzędne, a następnie do postów na cat_id =cat_id. Grupuj według left.cat_id i projektu przez cat_id i count(*).
Próbowałem tego w PostgreSQL 8.4 i nie widzę, dlaczego to nie zadziałałoby w MySQL, ponieważ zapytanie jest dość proste. Moje stoły:
create table categories(
cat_id varchar(40) primary key,
main_cat_id varchar(40) not null references categories,
title varchar(40) not null
)
create table posts (
post_id integer primary key,
cat_id varchar(40) not null references categories,
title varchar(40) not null
)
Moje zapytanie (grupowanie według tytułu, a nie identyfikatora):
select m.title, count(*)
from categories m, categories c, posts p
where m.cat_id = c.main_cat_id
and c.cat_id = p.cat_id
group by m.title
AKTUALIZACJA:Miałem też szansę na zrobienie tego za pomocą operacji na sznurku, tak jak próbował OP. Zapytanie (w języku SQL zgodnym ze standardami, akceptowanym przez PostgreSQL, a nie dialekt MySQL) to:
select m.title, count(*)
from categories m, posts p
where m.cat_id = substring(p.cat_id from 1 for 2)
group by m.title;
Co działa dobrze. Nie mogę zaoferować sensownego porównania szybkości, ale plan zapytania dla tego wyglądał nieco prostszy niż ten dla sprzężenia dwukierunkowego.