2009-06-03 17 views
14

¿Qué hay de malo en esta consulta:Mysql COUNT (*) en múltiples mesas

SELECT co.*, mod.COUNT(*) as moduleCount, vid.COUNT(*) as vidCount 
FROM courses as co, modules as mod, videos as vid 
WHERE mod.course_id=co.id AND vid.course_id=co.id ORDER BY co.id DESC 

En otras palabras, ¿cómo lo puedo hacer lo mismo con cada registro regresó de 'cursos', hay una columna adicional llamada ' modCount 'que muestra el número de registros en la tabla de módulos para ese curso_id, y otro llamado' vidCount 'que hace lo mismo para la tabla de videos.

error:

Error Number: 1064

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') as moduleCount, vid.COUNT() as vidCount FROM courses as co, ' at line 1

Respuesta

41

usando subselects que puede hacer:

SELECT co.*, 
    (SELECT COUNT(*) FROM modules mod WHERE mod.course_id=co.id) AS moduleCount, 
    (SELECT COUNT(*) FROM videos vid WHERE vid.course_id=co.id) AS vidCount 
FROM courses AS co 
ORDER BY co.id DESC 

Pero tenga cuidado, ya que es una consulta de cursos caros cuando tiene muchas filas.

EDIT: Si las tablas son bastante grandes la siguiente consulta debe realizar mucho mejor (a favor de ser más compleja de leer y entender).

SELECT co.*, 
    COALESCE(mod.moduleCount,0) AS moduleCount, 
    COALESCE(vid.vidCount,0) AS vidCount 
FROM courses AS co 
    LEFT JOIN (
      SELECT COUNT(*) AS moduleCount, course_id AS courseId 
      FROM modules 
      GROUP BY course_id 
     ) AS mod 
     ON mod.courseId = co.id 
    LEFT JOIN (
      SELECT COUNT(*) AS vidCount, course_id AS courseId 
      FROM videos 
      GROUP BY course_id 
     ) AS vid 
     ON vid.courseId = co.id 
ORDER BY co.id DESC 
+0

el gasto es una cosa importante a tener en cuenta, especialmente con varias subselects. – cori

+0

Tiene un error en su sintaxis SQL; revise el manual que corresponde a su versión de servidor MySQL para la sintaxis correcta para usar cerca de 'mod WHERE mod.course_id = co.id) como moduleCount, (SELECT COUNT (*)' en la línea 2 –

+0

Quedaba un "WHERE" que no pertenecía allí. Las súplicas tienen otra oportunidad. Si esto no funciona, su servidor MySQL no admite subsecuencias escalares. ¿Qué versión usa? –

2
SELECT co.*, 
     (
     SELECT COUNT(*) 
     FROM modules mod 
     WHERE mod.course_id = co.id 
     ) AS modCount, 
     (
     SELECT COUNT(*) 
     FROM videos vid 
     WHERE vid.course_id = co.id 
     ) AS vidCount 
FROM courses co 
ORDER BY 
     co.id DESC 
1
SELECT co.*, m.ModCnt as moduleCount, v.VidCnt as vidCount 
FROM courses co 
INNER JOIN (
     select count(*) AS ModCnt, co.id AS CoID 
     from modules 
     group by co) m 
    ON m.CoID = co.id 
INNER JOIN (
     select count(*) AS VidCnt, co.id AS CoID 
     from videos 
     group by co) v 
    ON v.CoID = co.id 
INNER JOIN videos vid 
    ON vid.course_id = co.id 
ORDER BY co.id DESC 
+5

simplemente me di cuenta de esto, modcnt, lol. ¿Se le permite usar 'cnt' como una forma abreviada de código relacionado con el trabajo? : D –

-2

Dispara esto. Me hizo el trabajo con algo de código no mysql:

function getAllWithStats($info='*',$order='',$id=0) 
{ 
    $courses=$this->getAll($info,$order,$id); 

    foreach ($courses as $k=>$v) 
    { 
     $courses[$k]['modCount']=$this->getModuleCount($v['id']); 
     $courses[$k]['vidCount']=$this->getVideoCount($v['id']); 
    } 

    return $courses; 
} 
+0

Esto es esencialmente lo mismo que la solución de subselección. Estás haciendo dos consultas adicionales para cada fila en la tabla de cursos, lo cual no es muy problemático si la tabla de cursos no es muy grande. –

+0

En cuanto a la solución de subselección y la solución de PHP, podría ser interesante que funcionaría mejor. Aunque la solución PHP tendrá cierta sobrecarga de red ya que los datos deben transmitirse por cable, la solución de subselección sufrirá por la falta del caché de consultas MySQL para sus subselecciones, aunque la consulta completa se almacenará en caché en el caché de consultas. –

10

tengo solución mejor y fácil

SELECT COUNT(*),(SELECT COUNT(*) FROM table2) FROM table1