web-dev-qa-db-fra.com

MySQL Multiple Left Goins

J'essaie de créer une page de nouvelles pour un site Web sur lequel je travaille. J'ai décidé d'utiliser les requêtes MySQL correctes (c'est-à-dire COUNT (id) et les jointures au lieu de plusieurs requêtes ou num_rows.) J'utilise un wrapper PDO qui devrait fonctionner correctement. Cette opération échoue quand elle est exécutée directement via le Application MySQL CLI.

En gros, j'ai 3 tables. L'un contient les informations, l'autre les commentaires et les utilisateurs. Mon but ici est de créer une page qui affiche tous les titres des nouvelles, les corps, les auteurs et les dates (pagineront plus tard). Cela a bien fonctionné lorsque j'ai utilisé une deuxième requête pour obtenir le nom d'utilisateur, mais j'ai alors décidé d'utiliser plutôt un JOIN.

Donc quel est le problème? Eh bien, j'ai besoin de deux jointures. L'une consiste à obtenir le nom d'utilisateur de l'auteur et l'autre à obtenir le nombre de commentaires. Lorsque je me contente du nom d'utilisateur de l'auteur, tout fonctionne comme prévu. Toutes les lignes (il y en a 2) dans la table d'actualités sont affichées. Cependant, lorsque j’ajoute ce deuxième joint gauche pour la ligne de commentaires, je ne reçois qu’une ligne de nouvelles (rappelez-vous, il y en a 2) et COUNT (comments.id) me donne 2 (il devrait afficher 1, comme j’ai un commentaire pour chaque post.)

Qu'est-ce que je fais mal? Pourquoi affiche-t-il seulement un article de presse et affirme-t-il qu'il a deux commentaires lorsqu'il y a deux articles de presse, chacun avec un commentaire?

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

De plus, juste pour être sûr d'une autre chose, ma jointure gauche aux commentaires est la bonne façon d'obtenir tous les messages, qu'ils aient ou non des commentaires, n'est-ce pas? Ou serait-ce un droit rejoindre? Oh, une dernière chose ... si je change de commentaire.news_id = news.id en news.id = comments.news_id, j'obtiens 0 résultats.

50
John M.

Il vous manque une clause 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 jointure gauche est correcte. Si vous utilisiez INNER ou RIGHT JOIN, vous n'obtiendrez pas de nouvelles sans commentaires.

94
Mark Byers

Pour afficher tous les détails pour chaque titre de publication, par exemple. "news.id" qui est la clé primaire, vous devez utiliser la clause GROUP BY pour "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
7
rizon

Pour afficher tous les détails pour chaque titre de publication, par exemple. "news.id" qui est la clé primaire, vous devez utiliser la clause GROUP BY pour "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
0
Youssof Hammoud