9
votes

SQL - JOIN DE GAUCHE - Compte

Supposons que j'ai deux tables. Articles et commentaires.

Lorsque je sélectionne des colonnes à partir de la table d'articles, je souhaite également sélectionner le nombre de commentaires sur l'article dans la même instruction SELECT ... (Supposons que le champ commun entre ces deux tables soit l'articleId)

Comment puis-je faire ça? Je peux le faire, mais je ne sais pas si mon chemin serait efficace, je veux donc apprendre la bonne façon.


0 commentaires

5 Réponses :


1
votes
SELECT 
       a.Article,
       a.ArticleID,
       t.COUNTOFCOMMENTS
FROM
       Article a
LEFT JOIN
       Comment c
ON c.ArticleID=a.ArticleID
LEFT JOIN
(SELECT ArticleID, COUNT(CommentID) AS COUNTOFCOMMENTS FROM Comments GROUP BY ArticleID) t
ON t.ArticleID = a.ArticleID

5 commentaires

Ajoutez donc une chose très simple.


@OP - Vous pouvez également supprimer le commentaire de join gauche C Si vous le souhaitez, je ne l'ai mis que là afin de pouvoir tirer des colonnes de la table des commentaires si vous le souhaitez.


Cela rendra une ligne pour chaque commentaire en raison de la première jointure gauche.


@Jbrooks, veuillez lire les commentaires sur @OP, comme je l'ai dit, vous pouvez vous débarrasser de la jointure gauche, il est là pour montrer la puissance de SQL ou de tout système de base de données relationnelle. Il permet à l'utilisateur de tirer des informations d'autres tables. De cette façon, s'il ne veut pas une simple regroupement par article, il / elle puisse obtenir des informations de commentaire à nouveau. Encore une fois, s'il vous plaît, veuillez lire les commentaires avant de poster.


@Jonh, j'ai lu les commentaires - je disais que si vous avez 10 commentaires pour l'article 1, l'article 1 sera répertorié 10 fois chacun avec un nombre de 10 à côté. Je ne pense pas que c'est ce qui a été demandé.



5
votes

Cela devrait le faire ..

SELECT
   article_column_1, article_column_2, count( ct.articleid) as comments
FROM
   article_table at
   LEFT OUTER JOIN comment_table ct ON at.articleid = ct.articleid
GROUP BY 
   article_column_1, article_column_2


2 commentaires

Vous voulez probablement un groupe par. Au cas où n'importe qui est concerné, cela retournera correctement 0 s'il n'y a pas de records joints.


Le Dorfier est correct - Cette requête ne fonctionnera pas sur SQL Server AS-IT.



7
votes

Utilisation:

   SELECT a.articleid, 
          COUNT(*) AS num_comments
     FROM ARTICLES a
LEFT JOIN COMMENTS c ON c.articleid = a.articleid
 GROUP BY a.articleid


3 commentaires

Il suffit d'ajouter un groupe par n'est pas toujours la meilleure chose à faire. Je vois que les gens écrivent des requêtes avec 100s (ok pas 100 ans mais beaucoup) de colonnes de leur groupe par clause parce qu'ils ne savent pas utiliser les agrégats correctement. C'est pourquoi j'ai posté une solution à l'aide d'une sous-requête.


@Jonh: SQL Server (parmi d'autres DBS) Similaire ne vous permettra pas de répertorier / retourner des colonnes qui ne sont pas emballées dans des fonctions globales (sauf si vous utilisez des fonctions analytiques) sans les définir dans le groupe par clause . Si vous omettez la clause GROUPE , vous Va Recevoir une erreur sur SQL Server en fonction de ce qui est fourni. MySQL est le seul dB qui prend en charge une telle fonctionnalité, et il est non standard: dev.mysql.com/doc/refman/5.0/fr/group-by-Hidden-columns.html


Je sais que mon point était une grande partie de gens ne comprennent pas comment le collecteur et les agrégats travaillent. J'ai vu des gens du groupe par des centièmes de colonnes juste pour obtenir ce qu'ils pensent être le résultat correct.



19
votes

Cela devrait être plus efficace car le groupe par n'est effectué que sur la table des commentaires.

SELECT  
       a.ArticleID, 
       a.Article, 
       isnull(c.Cnt, 0) as Cnt 
FROM Article a 
LEFT JOIN 
    (SELECT c.ArticleID, count(1) Cnt
     FROM Comment c
    GROUP BY c.ArticleID) as c
ON c.ArticleID=a.ArticleID 
ORDER BY 1


0 commentaires

2
votes
    -- Working Syntax example from my environment changed to fit this context. 
SELECT a.article
    ,A.articleid
    ,(
        SELECT Count(B.articleid)
        FROM dbo.comment AS B
        WHERE A.articleid = B.articleid
        ) AS comment#
    ,(
        SELECT Count(C.articleid)
        FROM dbo.comments AS C
        WHERE A.articleid = C.articleid
        ) AS comments#
FROM dbo.article AS A;

0 commentaires