Код SQL для получения только продуктов со средним значением выше средней глобальной цены для всех продуктов

#sql #aggregate

Вопрос:

Пытаюсь найти среднюю цену для категории и сравнить ее с общей средней стоимостью и сгруппировать только товары / категории, где средняя цена продукта> общая средняя стоимость.

 CREATE TABLE a (t int, q int);
    
INSERT INTO a (t, q)
VALUES
    (1, 6),
    (1, 6),
    (1, 4),
    (1, 8),
    (2, 6),
    (2, 4),
    (2, 1),
    (2, 1)
;
 

Мой код:

  select a.t, b.AvgQ as avg_group
 from a join 
 (select AVG(q) as AvgQ, t from a group by t) b on a.t=b.t
 where avg(a.q) < b.AvgQ
 group by a.t
 

Я пытался сравнить a.q (как среднюю цену для всех продуктов) с b.AvgQ как среднюю цену для одного типа продуктов. Однако я не могу использовать WHERE avg(a.q) .

В качестве решения я должен получить таблицу в виде:

 t | avg_group
-- ----------
1 | 6
 

Комментарии:

1. Какую СУБД вы используете? Помечать только определенные СУБД

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

3. Вы должны использовать HAVING предложение при проверке функций агрегирования (MAX, MIN, SUM, AVG и т. Д.)..

Ответ №1:

где средняя цена продукта> общая средняя стоимость.

Просто:

 SELECT t, avg(q) AS avg_group
FROM   a
GROUP  BY t
HAVING avg(q) > (SELECT avg(q) FROM a);
 

Выдает желаемый результат.

Ответ №2:

Вы не можете использовать функции агрегирования (MAX, MIN, SUM, AVG и т. Д.) В WHERE условии. Вы можете использовать HAVING или в вашем случае подзапрос работает отлично:

 select a.t, b.AvgQ as avg_group
from a 
inner join 
      ( select AVG(q) as AvgQ, t 
        from a 
        group by t) as b on a.t=b.t
 where (select avg(q) from a ) < b.AvgQ
 group by a.t ;
 

Демонстрация: https://www.db-fiddle.com/f/7yUJcuMJPncBBnrExKbzYz/138