2010-02-07 20 views
5

supponiamo di avere due tabelle. articoli e commenti.sql - left join - count

quando sto selezionando le colonne dalla tabella articoli, voglio anche selezionare il numero di commenti su questo articolo nella stessa istruzione select ... (supponiamo il campo comune tra queste due tabelle è articleId)

come lo faccio? Posso farcela, ma non so se il mio modo sarebbe efficiente, quindi voglio imparare nel modo giusto.

risposta

4

Usa:

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

Qualunque sia le colonne che si desidera dalla tabella ARTICLES, dovrete definire nella clausola GROUP BY perché non hanno una funzione di aggregazione eseguita su di loro.

+1

Aggiungere il gruppo non è sempre la cosa migliore da fare. Vedo che le persone scrivono query con 100s (ok non 100s ma un LOTTO) di colonne nel loro gruppo in base alla clausola perché non sanno come utilizzare gli aggregati correttamente. Questo è il motivo per cui ho pubblicato una soluzione utilizzando una sottoquery. – JonH

+0

@JonH: SQL Server (tra gli altri DB) simile non consente di elencare/restituire colonne che non sono racchiuse in funzioni aggregate (a meno che non si utilizzino funzioni analitiche) senza definirle all'interno della clausola 'GROUP BY'. Se si omette la clausola 'GROUP BY', ** si riceverà ** un errore su SQL Server in base a ciò che viene fornito. MySQL è l'unico DB che supporta tale funzionalità ed è non standard: http://dev.mysql.com/doc/refman/5.0/en/group-by-hidden-columns.html –

+0

So che il mio punto molte persone non capiscono come funzionano i gruppi e gli aggregati. Ho visto persone raggruppare per 100 di colonne solo per ottenere quello che pensano potrebbe essere il risultato corretto. – 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

Questo non funziona in quanto non v'è alcuna articleID nel subquery .. –

+0

in modo da aggiungere una roba molto semplice. – JonH

+0

@Gaby - modificato per mostrare l'id dell'articolo. – JonH

2

Questo dovrebbe farlo ..

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

Probabilmente vuoi un GROUP BY. Nel caso ci sia qualcuno interessato, questo restituirà correttamente 0 se non ci sono record uniti. – dkretz

+0

'le dorfier' è corretto - questa query non verrà eseguita su SQL Server così com'è. –

+0

sì, certo ragazzi ... modificato per lavorare .. –

7

Questo dovrebbe essere più efficiente perché il gruppo per è fatto solo sulla tabella dei commenti.

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;