Ваша группа - это то, что агрегирует ваше среднее значение, и она группируется по всей таблице (я предполагаю, что вы сделали это, чтобы разрешить выбор для всего). Просто переместите свой avg в другой подзапрос, удалите всеобъемлющую группу, и это должно реши это.
SELECT id, m_name AS "Mobile Name", cost AS Price,
(SELECT AVG(cost) FROM mobile) AS Average,
cost-(SELECT AVG(cost) FROM mobile) AS Difference
FROM mobile;
Когда вы запускаете базовый оператор SELECT AVG(cost)
, он естественным образом группируется по указанному столбцу (в данном случае - к стоимости), поскольку именно это вы запрашиваете. Я бы посоветовал прочитать больше о GROUP BY и агрегатах , чтобы лучше понять концепцию. Это должно помочь вам больше, чем просто решение.
UPDATE:
Ответ, приведенный ниже, фактически основан на ответе Давида. Это делает использование аналитических функций. По сути, происходит то, что при каждом вызове AVG вы указываете движку, что использовать для функции (в данном случае ничего). Достойную рецензию на аналитические функции можно найти здесь и здесь и более с Google по этому вопросу.
SELECT id, m_name AS "Mobile Name" cost AS Price, AVG(cost) OVER( ) AS Average,
cost - AVG(cost) OVER ( ) AS Difference
FROM mobile
Однако, если ваш движок SQL допускает переменные, вы также можете легко сделать ответ ниже. Я на самом деле предпочитаю это для будущей ремонтопригодности / удобочитаемости. Причина в том, что переменная с хорошим именем может быть очень наглядной для будущих читателей кода, в отличие от аналитической функции, которая требует немного больше работы для чтения (особенно если вы не понимаете функцию over).
Кроме того, это решение дублирует один и тот же запрос дважды, поэтому, возможно, стоит сохранить среднее значение в переменной SQL. Тогда вы можете изменить свое утверждение, чтобы просто использовать это глобальное среднее
Это переменные в SQL-сервере (вам придется адаптировать его для собственного экземпляра SQL)
DECLARE @my_avg INT;
SELECT @my_avg = AVG(cost) FROM Mobile;
SELECT id, m_name AS "Mobile Name", cost AS Price,
@my_avg AS Average, cost-@my_avg AS Difference
FROM mobile;
Это решение будет намного понятнее и для будущих читателей вашего SQL