2010-02-07 15 views
5

supongamos que tengo dos tablas. artículos y comentarios.sql - left join - count

cuando estoy seleccionando las columnas de la tabla artículos, yo también deseo seleccionar el número de observaciones sobre el artículo en la misma instrucción SELECT ... (supongamos que el campo común entre estas dos tablas es articleid)

cómo ¿Hago eso? Puedo hacerlo, pero no sé si mi camino sería eficiente, así que quiero aprender de la manera correcta.

Respuesta

4

Uso:

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

Cualquiera que sea columnas que desee de la tabla ARTICLES, que tendrá que definir en la cláusula GROUP BY porque no tienen una función agregada realizada en ellos.

+1

Solo agregar grupos no siempre es lo mejor que se puede hacer. Veo que las personas escriben consultas con 100s (ok no 100s pero MUCHO) de columnas en su cláusula group by porque no saben cómo usar los agregados correctamente. Es por eso que publiqué una solución usando una subconsulta. – JonH

+0

@JonH: SQL Server (entre otros DB) similar no le permitirá listar/devolver columnas que no están envueltas en funciones agregadas (a menos que se utilicen funciones analíticas) sin definirlas dentro de la cláusula 'GROUP BY'. Si omite la cláusula 'GROUP BY', ** recibirá ** un error en SQL Server en función de lo que se proporciona. MySQL es el único DB que admite dicha funcionalidad, y no es estándar: http://dev.mysql.com/doc/refman/5.0/en/group-by-hidden-columns.html –

+0

Sé que mi punto fue mucha gente que no entiende cómo funcionan los grupos y los agregados. He visto personas agrupadas por cientos de columnas solo para obtener lo que creen que podría ser el resultado correcto. – 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

Esto no funcionará ya que no hay articleID en su subconsulta .. –

+0

por lo que añadir una cosa muy simple. – JonH

+0

@Gaby - editado para mostrar la identificación del artículo. – JonH

2

Esto debe hacerlo ..

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

Probablemente quiera un GROUP BY. En caso de que a alguien le preocupe, esto devolverá correctamente 0 si no hay registros unidos. – dkretz

+0

'le dorfier' es correcto: esta consulta no se ejecutará en SQL Server como está. –

+0

sí, de hecho, muchachos ... editado para trabajar ... –

7

Esto debería ser más eficiente porque el grupo por solo se hace en la tabla de comentarios.

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;