Получение совокупных значений из нескольких таблиц - PullRequest
1 голос
/ 21 октября 2010

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

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

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

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

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

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

IЯ использую этот 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 ]

3 голосов
/ 21 октября 2010

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

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 голосов
/ 10 ноября 2012

(понимаю, это через два года) Я полагаю, что 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
...