Agregue una columna a Categorías que proporcione la categoría principal en la que se encuentra cada categoría (con las categorías principales dándose a sí mismas). Entonces:
cat_id | main_cat_id | title
-------+-------------+---------
01 | 01 | Science
0101 | 01 | Medicine
02 | 02 | Sport
Seleccione de esto en cat_id =main_cat_id para encontrar las categorías principales; únase de nuevo en sí mismo en left.cat_id =right.main_cat_id para encontrar las categorías secundarias, luego en las publicaciones en cat_id =cat_id. Agrupar por left.cat_id y proyectar sobre cat_id y contar (*).
Intenté esto en PostgreSQL 8.4 y no veo por qué esto no funcionaría en MySQL, ya que la consulta es bastante básica. Mis tablas:
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
)
Mi consulta (agrupación por título en lugar de 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
ACTUALIZACIÓN:También tuve la oportunidad de hacer que esto funcionara con una operación de cadena, como lo intentó el OP. La consulta (en SQL compatible con el estándar aceptado por PostgreSQL, en lugar del dialecto de MySQL) es:
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;
Que funciona bien No puedo ofrecer una comparación significativa en cuanto a la velocidad, pero el plan de consulta para esto parecía un poco más simple que el de la unión bidireccional.