2009-06-03 2 views
14

Что случилось с этим запросом:Mysql COUNT (*) на нескольких столах

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 

Другими словами, как я могу сделать это так с каждой записью возвращается из «курсов», есть дополнительный столбец под названием ' modCount ', который показывает количество записей в таблице модулей для этого course_id, а другое -' vidCount ', которое делает то же самое для таблицы видео.

Ошибка:

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

ответ

41

Использование подзапросов вы можете сделать:

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 

Но будьте осторожны, так как это дорогой запрос, когда курсы имеет множество строк.

EDIT: Если таблицы достаточно большие следующий запрос должен работать гораздо лучше (в пользу того, чтобы быть более сложными для чтения и понимания).

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

расход - это важная вещь, о которой нужно помнить, особенно с несколькими подзапросами. – cori

+0

У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с модулем WHERE mod.course_id = co.id в качестве moduleCount, (SELECT COUNT (*) 'в строке 2 –

+0

Осталось "WHERE" там не было. У вас есть еще одна попытка: если это не работает, ваш сервер MySQL не поддерживает скалярные подзапросы. Какую версию вы используете? –

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

Я только заметил это, modcnt, лол. Можно ли использовать «cnt» в качестве сокращенного кода, связанного с работой? : D –

-2

Снять это. Я сделал работу с нек-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

Это по существу то же самое, что и подзапрос-решение. Вы делаете два дополнительных запроса для каждой строки в таблице курсов, что не очень проблематично, если таблица курсов не очень велика. –

+0

Глядя на решение подзаголовка и решение PHP, может быть интересно, что будет работать лучше. Несмотря на то, что решение PHP будет иметь некоторые сетевые издержки, поскольку данные должны быть переданы на проводе, подзапрос будет страдать от нехватки кэша запросов MySQL для его подзадач - хотя полный запрос будет кэшироваться в кеше запросов. –

10

у меня есть лучшее решение и легко

SELECT COUNT(*),(SELECT COUNT(*) FROM table2) FROM table1 
Смежные вопросы