2010-10-21 6 views
0

Я пытаюсь получить некоторые совокупные значения из разных таблиц, но моя проблема в том, что они возвращаются некорректно, т. Е. Как умножения друг на друга.Извлечение совокупных значений из нескольких таблиц

У меня есть эти таблицы:

Institutes 
---------- 
ID 
name 

Conversions 
----------- 
ID 
institute_id 
training_id 

Trainings 
--------- 
ID 
institute_id 

И я хочу получить Institute.name, количество конверсий и количество тренировок. Я могу получить имя и одно из совокупных значений, но когда я пытаюсь получить оба значения, он возвращает неправильный номер, потому что он будет повторять все преобразования для каждого обучения (или наоборот).

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

SELECT Institute.id 
      ,Institute.name 
      ,Institute.friendly_url 
      ,count(Training.`id`) as totalTrainings 
      ,count(Conversion.`id`) AS totalConversions 
FROM  institutes Institute 
      LEFT JOIN trainings Training  ON Institute.`id` = Training.`institute_id`  
      LEFT JOIN conversions Conversion ON Training.`institute_id` = Conversion.`institute_id` 
GROUP BY 1,2,3 

Мне нужно добавить несколько таблиц, в дальнейшем, используя ту же структуру, а также с единственной целью извлечения агрегатов. Я могу заставить его работать, используя несколько запросов, но затем я столкнулся с проблемой неспособности использовать правильную сортировку, разбивку на страницы и проблемы, когда я хочу фильтровать данные.

Создание представления - это решение, о котором я тоже думал, но мне все еще нужен некоторый SQL для создания этого представления.

Я также пытался поработать с GROUP BY, но безрезультатно.

Обновление Теперь я использую подзапросы в моем соединении, которое, похоже, работает. Есть ли более оптимальное решение?

SELECT Institute.id 
      ,Institute.name 
      ,Institute.friendly_url 
      ,Training.total 
      ,Conversion.total 
FROM  institutes Institute 
      LEFT JOIN (SELECT institute_id, count(id) AS total 
        FROM `trainings` 
        GROUP BY institute_id) AS Training ON Training.institute_id = Institute.id 
      LEFT JOIN (SELECT institute_id, count(id) AS total 
        FROM `conversions` 
        GROUP BY institute_id) AS Conversion ON Conversion.institute_id = Institute.id 

ответ

2

Попробуйте это. Выполнение отдельных подзапросов лучше ИМХО. И выглядит также лучше, проще читать запрос.

SELECT  
Institute.id 
,Institute.name 
,Institute.friendly_url 
,(SELECT count(Training.`id`) FROM trainings Training WHERE Institute.`id` = Training.`institute_id` LIMIT 1) as totalTrainings 
,(SELECT count(Conversion.`id`) FROM conversions Conversion ON Institute.`id` = Conversion.`institute_id` LIMIT 1) AS totalConversions 
FROM institutes Institute 
+0

Это дает синтаксическую ошибку для первого (и второго) подзапроса в выборе. Кстати, подзапрос - хорошая идея. Использование подзапроса в моем соединении, похоже, дает правильные подсчеты. – vindia

+0

Я немного поменял его, попробуйте еще раз. Я не вижу, что еще может вызвать проблему с подзапросами в моем ответе. Какая ошибка возникает при запуске примера? Правильно ли указаны столбцы? –

+0

Это работает, спасибо. Я решил использовать подзапрос подход из обновления моего сообщения, хотя, потому что я думаю, что это немного легче читать и быстрее тоже. Благодаря! – vindia

0

(понимаю, что это два года спустя) Я считаю, что DISTINCT в вашей статье COUNT бы решить эту проблему.

SELECT Institute.id 
      ,Institute.name 
      ,Institute.friendly_url 
      ,count(DISTINCT Training.`id`) as totalTrainings 
      ,count(DISTINCT Conversion.`id`) AS totalConversions 
FROM  institutes Institute 
      LEFT JOIN trainings Training  ON Institute.`id` = Training.`institute_id`  
      LEFT JOIN conversions Conversion ON Training.`institute_id` = Conversion.`institute_id` 
GROUP BY 1,2,3 
Смежные вопросы