2017-01-06 9 views
0

Имейте SQL-запрос, как это:MySQL, группа по в обоих внутреннем и внешнем запросе, в то же время

SELECT position, AVG(price) FROM products WHERE position IS NOT NULL 
AND price < (SELECT AVG(price)+2*STDDEV(price) FROM price) 
AND position = 3 

Nice, если вы просто хотите, чтобы проверить одну позицию в то время, но у меня есть немало позиции, и поэтому я хотел бы получить данные для всех позиций одновременно.

т.е. что-то вроде:

[QUERY]... GROUP BY position 

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

Спасибо.

+0

См. Http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-to-be-a-very-simple- sql-query – Strawberry

+0

Почему рейтинг -1? – Louisa

+0

Наведите указатель на стрелку вниз – Strawberry

ответ

1

Вы ищете GROUP BY. Чтобы получить среднюю цену за каждую позицию, а не только за одну позицию, вот что вы делаете.

SELECT position, AVG(price) average 
    FROM products 
GROUP BY position 

У вас есть исключение из двух сигм в вашем запросе. Вы должны использовать ту же технику, чтобы получить предел для каждой позиции. Если вы хотите вычислить средний + 2 лимит сигмы для каждой позиции, вам нужен этот подзапрос. (Примечание: Лучше всего использовать круглые скобки в языках программирования, как SQL, а не доверяя арифметический оператор приоритет.)

    SELECT position, 
         AVG(price) + (2.0 * STDDEV(price)) upper_limit 
        FROM products 
        GROUP BY position 

Вы можете присоединиться к этому запрос к папке верхнего уровня выбрать как так

SELECT a.position, a.price 
    FROM products 
    JOIN (
       SELECT position, 
         AVG(price) + (2.0 * STDDEV(price)) upper_limit 
        FROM products 
        GROUP BY position 
     ) b ON a.position = b.position 
      AND a.price < b.upper_limit 

Это дает вам необработанные данные для позиции/цены, исключая ваши выбросы. Вы видите, как предложение ON соответствует строкам в основном и подзапросе по положению, а затем отфильтровывает строки, где исходная цена выше upper_limit? Это трюк.

Затем вы можете объединить эти данные с типичным GROUP BY.

SELECT a.position, AVG(a.price) average 
    FROM products 
    JOIN (
       SELECT position, 
         AVG(price) + (2.0 * STDDEV(price)) upper_limit 
        FROM products 
        GROUP BY position 
     ) b ON a.position = b.position 
      AND a.price < b.upper_limit 
    GROUP BY a.position 

Это наслоение подзапросов внутри запросов почему это называется язык структурированных запросов.

+0

Отлично. Большое спасибо! – Louisa

0

Не добавляет GROUP BY выполнить то, что вы хотите?

SELECT position, AVG(price) 
FROM products p 
WHERE position IS NOT NULL AND 
     price < (SELECT AVG(price)+2*STDDEV(price) 
       FROM price p2 
      ) 
GROUP BY position; 

Или, есть ли какой-то конкретный продукт, о котором вы заботитесь? Если это так, вам нужен коррелированный подзапрос:

SELECT position, AVG(price) 
FROM products p 
WHERE position IS NOT NULL AND 
     price < (SELECT AVG(price)+2*STDDEV(price) 
       FROM price p2 
       WHERE p.? = p2.? 
      ) 
GROUP BY position; 

Непонятно, какой столбец следует использовать для корреляции.

+0

Спасибо, но верхний запрос не ограничивает stddev текущей позицией (т. Е. Каждой из позиций, которые мы группируем). Поэтому вместо фильтрации stddev для текущей позиции мы фильтруем для stddev всех строк в таблице. – Louisa