2010-02-07 7 views
5

Supposons que j'ai deux tables. articles et commentaires.sql - left join - count

quand je suis sélectionner des colonnes de la table d'articles, je veux également sélectionner le nombre de commentaires sur l'article de la même instruction select ... (supposons que le champ commun entre ces deux tables est articleid)

comment Est-ce que je fais ça? Je peux le faire, mais je ne sais pas si mon chemin serait efficace, alors je veux apprendre de la bonne façon.

Répondre

4

Utilisation:

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

Quelle que soit les colonnes que vous voulez à partir de la table ARTICLES, vous devrez définir dans la clause GROUP BY parce qu'ils ne pas avoir une fonction agrégée effectuée sur eux.

+1

Juste ajouter un groupe n'est pas toujours la meilleure chose à faire. Je vois des gens écrire des requêtes avec des centaines de colonnes (ok pas 100s mais beaucoup) dans leur clause group by parce qu'elles ne savent pas comment utiliser correctement les agrégats. C'est pourquoi j'ai posté une solution en utilisant une sous-requête. – JonH

+0

@JonH: SQL Server (entre autres DB) similaire ne vous permettra pas de lister/retourner les colonnes qui ne sont pas enveloppées dans des fonctions agrégées (sauf si vous utilisez des fonctions analytiques) sans les définir dans la clause GROUP BY. Si vous omettez la clause 'GROUP BY', vous ** recevrez une erreur sur SQL Server en fonction de ce qui est fourni. MySQL est le seul DB qui supporte une telle fonctionnalité, et il est non-standard: http://dev.mysql.com/doc/refman/5.0/en/group-by-hidden-columns.html –

+0

Je sais que mon point Beaucoup de gens ne comprennent pas comment fonctionnent les groupes et les agrégats. J'ai vu des gens grouper par 100s de colonnes juste pour obtenir ce qu'ils pensent être le bon résultat. – JonH

0
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 
+0

Cela ne fonctionnera pas car il n'y a pas articleID dans votre sous-requête .. –

+0

ajouter donc un truc très simple. – JonH

+0

@Gaby - édité pour afficher l'identifiant de l'article. – JonH

2

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 
+1

Vous voulez probablement un GROUP BY. Dans le cas où quelqu'un est concerné, cela retournera correctement 0 s'il n'y a pas d'enregistrements joints. – dkretz

+0

'le dorfier' est correct - cette requête ne s'exécutera pas sur SQL Server tel quel. –

+0

oui en effet les gars ... édité pour travailler .. –

7

Cela devrait être plus efficace car le groupe par n'est fait 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
-- 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;