MySQL: El número de comentarios

Si un post pudiera tener asociadas N categorías y a su vez M comentarios sería un super-post. Y si todo ello pretende estar normalizado en una base de datos relacional, con sus tablas independientes, sus keys y sus índices... ¡a quién no le gustaría ser post!.

El problema viene cuando un programador pretende sacar en la misma consulta -por aquello de no ahogar más si cabe el cuello de botella- los datos principales del post y el número de comentarios que tiene. Todo ello perteneciente a una categoría -category_id=9 en el ejemplo-. Pónganse los cinturones.

Opción 1

Sin mucho pensar y abordando el tema desde la poca experiencia que me aportan los JOIN:
SELECT posts.*, count(comments.id) as cuenta
FROM posts

LEFT JOIN comments
ON comments.post_id = posts.id

LEFT JOIN posts_categories
ON posts.id = posts_categories.post_id

WHERE  posts_categories.category_id = 9
GROUP BY posts.id ORDER BY id DESC
Después de la adrenalina inicial y haciendo algunas pruebas me doy cuenta de que no funciona (al menos no sirve para solucionar el problema)... descartada.

Opción 2

La que -rotulador en mano- pensó minuciosamente mi compañero Mamel:
SELECT p.*, cuenta
FROM posts_categories pc 

LEFT JOIN 
(
	posts p
	LEFT JOIN 
	
	(
		SELECT count(*) AS cuenta, post_id
		FROM comments
		WHERE post_id IN
		(
			SELECT post_id 
			FROM posts_categories
			WHERE posts_categories.category_id = 9
		)
		GROUP BY post_id
	) c
	ON c.post_id = p.id
) p 
ON pc.post_id = p.id

WHERE pc.category_id = 9;
Todo parecía ir bien hasta que probamos con un post sin comentarios. Semi-descartado.

Opción 3

Lo más sencillo sería guardar el número de comentarios directamente en la tabla de posts, ahorrando tiempo, código y ciclos de reloj. Merece la pena modificar el fuente existente para adecuarse a la nueva situación.

Nota mental

Enlaces toread sobre joins y full text search (que no viene al caso pero me apetece leer):

About the author

Óscar
has doubledaddy super powers, father of Hugo and Nico, husband of Marta, *nix user, Djangonaut and open source passionate.