2010-01-02 14 views
42

Estoy tratando de crear una página de noticias para un sitio web en el que estoy trabajando. Decidí que quería usar las consultas correctas de MySQL (es decir, COUNT (id) y join en lugar de más de una consulta o num_rows.) Estoy usando un contenedor PDO, que debería funcionar bien, y esto aún falla cuando se ejecuta directamente a través del Aplicación MySQL CLI.MySQL Multiple Left Joins

Básicamente, tengo 3 tablas. Uno tiene las noticias, uno contiene los comentarios y uno retiene a los usuarios. Mi objetivo aquí es crear una página que muestre todo (va a paginar más adelante) los títulos, cuerpos, autores y fechas de las publicaciones. Esto funcionó bien cuando usé una segunda consulta para obtener el nombre de usuario, pero luego decidí que prefería usar un JOIN.

¿Cuál es el problema? Bueno, necesito dos uniones. Uno es obtener el nombre de usuario del autor y el otro para obtener la cantidad de comentarios. Cuando simplemente busco el nombre de usuario del autor, todo funciona como se espera. Se muestran todas las filas (hay 2) en la tabla de noticias. Sin embargo, cuando agregué este segundo LEFT JOIN para la fila de comentarios, termino recibiendo solo una fila de las noticias (recuerde, hay 2) y COUNT (comments.id) me da 2 (debería mostrar 1, ya que tengo un comentario para cada publicación.)

¿Qué estoy haciendo mal? ¿Por qué solo muestra una publicación de noticias y dice que tiene dos comentarios cuando hay dos publicaciones, cada una con un comentario?

SELECT news.id, users.username, news.title, news.date, news.body, COUNT(comments.id) 
FROM news 
LEFT JOIN users 
ON news.user_id = users.id 
LEFT JOIN comments 
ON comments.news_id = news.id 

Además, sólo para estar seguro de una cosa, mi izquierda unirse a los comentarios es la forma correcta para obtener todos los mensajes, independientemente de si tienen comentarios o no, ¿verdad? ¿O sería una unión correcta? Oh, una última cosa ... si cambio comments.news_id = news.id a news.id = comments.news_id, obtengo 0 resultados.

Respuesta

80

Te estás perdiendo una cláusula GROUP BY:

SELECT news.id, users.username, news.title, news.date, news.body, COUNT(comments.id) 
FROM news 
LEFT JOIN users 
ON news.user_id = users.id 
LEFT JOIN comments 
ON comments.news_id = news.id 
GROUP BY news.id 

La combinación izquierda es correcta. Si usó INNER o RIGHT JOIN, entonces no obtendría noticias que no tuvieran comentarios.

+0

¿TIENE QUE USAR EL AGRUPAR POR? Mi doble combinación de novatos no está funcionando, y estoy tratando de descubrir por qué. –

+0

Gracias - me ayudó a resolver un problema que fue lo suficientemente difícil para mí para pasar 3 horas - resuelto en cuestión de minutos – Muhammad

+0

Muchas gracias. Resolvió mi problema también :). – C4u

7

Para mostrar todos los detalles de cada título de la publicación de noticias, es decir. "news.id" que es la clave principal, necesita usar la cláusula GROUP BY para "news.id"

SELECT news.id, users.username, news.title, news.date, 
     news.body, COUNT(comments.id) 
FROM news 
LEFT JOIN users 
ON news.user_id = users.id 
LEFT JOIN comments 
ON comments.news_id = news.id 
GROUP BY news.id 
Cuestiones relacionadas