Fügen Sie Kategorien eine Spalte hinzu, die die Hauptkategorie angibt, in der sich jede Kategorie befindet (wobei sich die Hauptkategorien selbst angeben). Also:
cat_id | main_cat_id | title
-------+-------------+---------
01 | 01 | Science
0101 | 01 | Medicine
02 | 02 | Sport
Wählen Sie daraus cat_id =main_cat_id aus, um Hauptkategorien zu finden; verbinden Sie sich wieder mit sich selbst auf left.cat_id =right.main_cat_id, um die untergeordneten Kategorien zu finden, und dann auf Beiträge auf cat_id =cat_id. Gruppieren Sie nach left.cat_id und projizieren Sie über cat_id und count(*).
Ich habe dies in PostgreSQL 8.4 ausprobiert, und ich verstehe nicht, warum dies in MySQL nicht funktionieren würde, da die Abfrage ziemlich einfach ist. Meine Tabellen:
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
)
Meine Abfrage (Gruppierung nach Titel statt ID):
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
UPDATE:Ich hatte auch versucht, dies mit einer String-Operation zum Laufen zu bringen, wie es das OP versuchte. Die Abfrage (in standardkonformem SQL, wie es von PostgreSQL akzeptiert wird, und nicht im Dialekt von MySQL) lautet:
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;
Was gut funktioniert. Ich kann keinen aussagekräftigen Vergleich hinsichtlich der Geschwindigkeit anbieten, aber der Abfrageplan dafür sah etwas einfacher aus als der für den Zwei-Wege-Join.