Получение данных из объединенных таблиц MySQL с использованием AVG в предложении WHERE?

Я пытаюсь выбрать данные из нескольких таблиц, которые используют AVG в предложении WHERE.

SELECT company_metrics.*, companies.company_name, companies.permalink 
FROM company_metrics LEFT JOIN companies 
     ON companies.company_id = company_metrics.company_id
WHERE MONTH(date) = '04' AND YEAR(date) = '2011' 
HAVING (SELECT avg(company_unique_visitors) 
        FROM (SELECT company_metrics.company_unique_visitors 
              FROM company_metrics  
              ORDER BY company_metrics.date DESC LIMIT 3)
        average ) >'2000' 
ORDER BY date DESC

Пример данных:

###Company Metrics#### Table
company_id       company_unique_visitors       date
-----------      -----------------------       ----
     604                    2054               2011-04-01
     604                    3444               2011-03-01
     604                    2122               2011-02-01
     604                    2144               2011-01-01
     604                    2001               2010-12-01
     602                    2011               2011-04-01
     602                    11                 2011-03-01
     602                    411                2011-02-01
     602                    611                2011-01-01
     602                    111                2010-12-01

EDIT Мне нужны только 3 последних номера от company_unique_visitors AVG, обработанные /EDIT

Таким образом, запрос выберет company_id 604, но не выберет company_id 602, потому что 602 не имеет AVG больше 2000.

Мне нужна помощь в написании правильного запроса, чтобы сделать то, что я описал. Могу уточнить, если нужно. Спасибо за вашу помощь!


person Brian C    schedule 23.05.2011    source источник
comment
Спасибо за редактирование. Это выглядело немного долго.   -  person Brian C    schedule 23.05.2011


Ответы (2)


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

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

И, без лишних церемоний, вот фиксированный запрос:

SELECT limited_metrics.*, companies.company_name, companies.permalink,
       avg(limited_metrics.company_unique_visitors) AS avg_visitors 
FROM 
  (SELECT *
   FROM company_metrics
   ORDER BY company_metrics.date DESC LIMIT 3) AS limited_metrics
  LEFT JOIN companies 
  ON companies.company_id = limited_metrics.company_id
WHERE MONTH(limited_metrics.date) = '04' AND YEAR(limited_metrics.date) = '2011'
GROUP BY companies.company_id
HAVING avg_visitors > 2000
person Jared Harding    schedule 23.05.2011
comment
Да спасибо! Запрос, который я опубликовал изначально, был скопированным и вставленным кошмаром, который, как я знал, был далеко не тем, чем должен был быть. В конце концов я сдался и выложил то, что у меня было. - person Brian C; 23.05.2011
comment
Хорошо, после некоторого сна и игры с ним, это не совсем то, на что я надеялся (хотя это близко!). Позвольте мне немного уточнить: приведенный выше запрос захватывает только 3 компании из таблицы company_metrics. Я хотел бы, чтобы он захватывал каждую отдельную метрику company_metric, а затем выполнял среднее значение для последних 3 строк company_unique_visitors для каждой компании. Другими словами: возьмите все company_metrics, отсортируйте их по AVG последних 3 строк company_unique_visitors для этой компании и верните все, у которых значение company_unique_visitors больше 2000. Надеюсь, это имеет смысл. :) - person Brian C; 23.05.2011
comment
Я ответил себе на основе вашего запроса. Спасибо еще раз! - person Brian C; 24.05.2011

Хорошо, основываясь на ответе Джареда Хардинга и этом сообщении: Скользящее среднее — MySQL Мне удалось выяснить запрос.

SELECT metrics.*,companies.company_name,companies.permalink
FROM (SELECT company_id,AVG(company_unique_visitors) AS met_avg
      FROM company_metrics
     WHERE `date` BETWEEN DATE_SUB(NOW(), INTERVAL 4 MONTH) AND NOW()
  GROUP BY company_id HAVING met_avg>2000) AS metrics
LEFT JOIN companies ON companies.company_id=metrics.company_id

Спасибо, Джаред, за помощь!

person Brian C    schedule 23.05.2011