2008-11-13 8 views
1

Je dois construire un SQL assez simple, je suppose, mais comme c'est un événement rare que je travaille avec des DB ces jours-ci, je ne peux pas comprendre les détails.SQL: Obtenir tous les messages avec des commentaires

J'ai une table 'postes' avec les colonnes suivantes:

id

, légende, texte

et 'commentaires' d'une table avec les colonnes suivantes:

id, nom, texte, post_id

Qu'est-ce que t L'instruction SQL (unique) ressemble-t-elle à celle qui récupère les légendes de tous les articles auxquels un ou plusieurs commentaires sont associés via la clé 'post_id'? Le SGBD est MySQL s'il est pertinent pour la requête SQL.

Répondre

7
select p.caption, count(c.id) 
from posts p join comments c on p.id = c.post_id 
group by p.caption 
having count (c.id) > 0
+0

le HAVING et COUNT est unnessesry car il veut tout ce qui a 1 OU plus de commentaires. et utilisez INNER JOIN pour plus de clarté, même si la jointure interne est la valeur par défaut. – jishi

+0

et GROUP BY p.id à la place, car ce sera probablement la clé primaire. – jishi

+0

Il devrait être "...> 0" plutôt que "...> 1", sinon que ça a l'air bien :) –

-2

Vous êtes à la recherche essentiellement à effectuer une sous-requête -

SELECT p.caption FROM posts p WHERE (SELECT COUNT(*) FROM comments c WHERE c.post_id=p.id) > 1;

Cela a pour effet d'exécuter la sous-requête SELECT COUNT(*) pour chaque ligne de la table des postes. En fonction de la taille de vos tables, vous pouvez envisager d'ajouter une colonne supplémentaire, comment_count, dans votre table posts pour stocker le nombre de correspondants comments, de sorte que vous pouvez simplement faire

SELECT p.caption FROM posts p WHERE comment_count > 1

+0

Nooo! La dénormalisation ne devrait jamais être préconisée pour quelque chose d'aussi simple. – FlySwat

-1

Juste aller du haut de ma tête ici, mais peut-être quelque chose comme:

SELECT caption FROM posts WHERE id IN (SELECT post_id FROM comments HAVING count(*) > 0) 
2
SELECT DISTINCT p.caption, p.id 
    FROM posts p, 
     comments c 
    WHERE c.post_ID = p.ID 

Je pense à l'aide d'une jointure wo uld serait beaucoup plus rapide que d'utiliser la clause IN ou une sous-requête.

+0

mais le vôtre est meilleur. – jishi

+0

Je ne suis pas sûr si DISTINCT fonctionnerait ici, ou si je devais l'imbriquer dans une sous-requête, c'est-à-dire, SELECT DISTINCT Légende FROM (ma requête) ... mais je pensais que je le jetterais là. – FlySwat

+0

Je crois que ça marcherait ici puisque légende et p.id seraient égaux pour chaque publication. – jishi

0

SELECT légende FROM messages INNER JOIN commentaires sur comments.post_id = posts.id GROUP BY posts.id;

Pas besoin d'une clause having ou count().

edit: Doit être un innerjoin bien sûr (pour éviter les zéros si un commentaire est orphelin), grâce à jishi.

+0

que l'on lui donnerait des messages nuls pour les commentaires orphelins, ce qui est une mauvaise idée. une jointure à gauche donnerait des zéros pour les commentaires. Une jointure interne est la voie à suivre. – jishi

0
SELECT DISTINCT caption 
FROM posts 
    INNER JOIN comments ON posts.id = comments.post_id 

Oubliez les comptes et les sous-requêtes.

La jointure interne récupère tous les commentaires qui ont des messages valides et exclut tous les messages qui ont 0 commentaire. DISTINCT fusionnera les entrées de légende en double pour les publications qui ont plus d'un commentaire.

+0

MySQL n'a pas la syntaxe de jointure interne déduite (regardez mon article ci-dessous qui est T-SQL) – FlySwat

0

Je trouve cette syntaxe pour être le plus lisible dans cette situation:

SELECT * FROM posts P 
    WHERE EXISTS (SELECT * FROM Comments WHERE post_id = P.id) 

Il exprime votre intention mieux que la plupart des autres dans ce fil - « me donner tous les postes ... » (sélectionnez * des messages) "... qui ont des commentaires" (où existent (sélectionnez * dans les commentaires ...)).C'est essentiellement la même chose que les jointures ci-dessus, mais parce que vous n'êtes pas en train de faire une jointure, vous n'avez pas à vous soucier d'obtenir des doublons des enregistrements dans Posts, donc vous ne recevrez qu'un enregistrement par publication.

+0

Vous avez également posté la requête la plus lente encore =) – FlySwat

+0

Hmm ... Je pense que cela dépend du moteur DB. La requête n'est pas * intrinsèquement * plus lente, car elle est équivalente sur le plan relationnel à une jointure. Un bon optimiseur devrait l'exécuter aussi vite qu'une jointure, ou plus vite s'il peut éviter de matérialiser les résultats de jointure pour le distinct. Bien sûr, je ne l'ai pas testé. :) –

Questions connexes