2013-07-17 3 views
0

Я пытаюсь получить данные из 2 таблиц с помощью одного оператора SQL, используя объединения. Идея довольно проста. У проекта есть участники, и в обзоре проекта я хочу показать информацию о проекте с количеством участников.LEFT OUTER JOIN не показывает все строки?

Сейчас есть 2 проекта, один проект с участниками и другой проект без участников.

Я использую этот запрос:

SELECT SQL_CALC_FOUND_ROWS `p`.`id`, 
     `p`.`title`, 
     `p`.`live`, 
     `p`.`startDate`, 
     `p`.`endDate`, 
     COUNT(`part`.`id`) AS `participants` 
FROM `projects` `p` 
LEFT OUTER JOIN `participants` `part` 
    ON `p`.`id` = `part`.`projectid` 
ORDER BY `p`.`live` DESC, 
     `p`.`startDate` DESC 
LIMIT 0,10 

Проблемы, этот запрос возвращает только проект с участниками и один без участников опущен.

Что я здесь делаю неправильно?

ответ

5

Вы должны использовать GROUP BY

SELECT SQL_CALC_FOUND_ROWS `p`.`id`, 
     `p`.`title`, 
     `p`.`live`, 
     `p`.`startDate`, 
     `p`.`endDate`, 
     COUNT(`part`.`id`) AS `participants` 
FROM `projects` `p` 
LEFT OUTER JOIN `participants` `part` 
    ON `p`.`id` = `part`.`projectid` 
GROUP BY `p`.`id`, 
     `p`.`title`, 
     `p`.`live`, 
     `p`.`startDate`, 
     `p`.`endDate` 
ORDER BY `p`.`live` DESC, 
     `p`.`startDate` DESC 
LIMIT 0,10 

Вот SQLFiddle демо

+0

Это сработало! Благодаря! Не могли бы вы объяснить мне почему? Теперь я знаю, что это работает, но у меня нет идеи, почему это работает. – SheperdOfFire

+1

Вы должны использовать 'GROUP BY', так как вы применяете агрегированную функцию' COUNT() 'и хотите получать результаты для каждой группы (в вашем случае для каждого проекта), а не одно значение. – peterm

+0

На самом деле меня сейчас интересует, как выглядит производительность этого взгляда по сравнению с коррелированным подзапросом? Было бы это похоже или могло бы быть потенциально более эффективным? – Kaiwa

3

Я не думаю, что это должно быть сделано с помощью JOIN, а с коррелированным подзапросом.

SELECT SQL_CALC_FOUND_ROWS `p`.`id`, 
    `p`.`title`, 
    `p`.`live`, 
    `p`.`startDate`, 
    `p`.`endDate`, 
    (SELECT COUNT(`part`.`id`) FROM `participants` `part` WHERE `part`.`projectid` = `p`.`id`) AS `participants` 
FROM `projects` `p` 
ORDER BY `p`.`live` DESC, 
    `p`.`startDate` DESC 
LIMIT 0,10 
+0

Но в соответствии с этим: http://www.codinghorror.com/blog/2007/10/a -visual-explain-of-sql-joins.html Должно быть возможно сделать это с помощью соединения, некоторые записи должны содержать нуль или что-то в этом роде. Я знаю, что это можно сделать с помощью подзапроса, но это выглядит не так хорошо, как я думаю. – SheperdOfFire

+0

Тогда вам нужно будет взглянуть на его решение. Оба эти запроса дают тот же результат, его, вероятно, тот, который вы хотите! – Kaiwa