Как вычислить среднее значение столбца и затем включить его в запрос select в oracle?



Мой стол--



create table mobile
(
id integer,
m_name varchar(20),
cost integer
)


А значения --



insert into mobile values(10,'NOkia',100);
insert into mobile values(11,'Samsung',150);
insert into mobile values(12,'Sony',120);


Я знаю, как вычислить среднее значение по стоимости столбца, мой код--



 select avg(cost) from mobile;


И результат таков:123



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

Мой код - - -



SELECT id, m_name as "Mobile Name", cost as Price,avg(cost) as Average,
cost-(select avg(cost) from mobile) as Difference FROM mobile
group by id,m_name,cost;


И выход-



id      Mobile Name   Price  Average  Difference 
10 Nokia 100 100 -23
11 Samsung 150 150 27
12 Sony 120 120 -3


Я хочу исправить эту среднюю колонку.. Я хочу это - - -



id      Mobile Name  Price  Average  Difference 
10 Nokia 100 123 -23
11 Samsung 150 123 27
12 Sony 120 123 -3


Пожалуйста, помогите...

503   6  

6 ответов:

Ваша группа by-это то, что агрегирует ваше среднее значение, и это группировка по всей таблице (я предполагаю, что вы сделали это, чтобы разрешить выбор для всего) просто переместите ваш avg в другой подзапрос, удалите всеобъемлющую группу by, и это должно решить ее.

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), он естественно группируется по указанному столбцу (стоимость в данном случае), поскольку это то, что вы запрашиваете. Я бы предложил прочитать больше о группе по и агрегатам чтобы лучше понять эту концепцию. Это должно помочь вам больше, чем просто простое решение.

Обновление:

Ответ ниже на самом деле из ответа Дэвида. Он использует аналитические функции. В основном, происходит то, что при каждом вызове 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, тоже

Поскольку вы используете Oracle, вы должны иметь возможность использовать AVG () в качестве аналитической (оконной) функции:

SELECT id, m_name AS "Mobile Name" cost AS Price, AVG(cost) OVER( ) AS Average
     , cost - AVG(cost) OVER ( ) AS Difference
  FROM mobile

Нет необходимости в подзапросах или группировке по.

Самое простое изменение-это изменение avg(cost) as Average на (select avg(cost) from mobile) as Average. Это также означает, что вам больше не понадобится предложение GROUP BY (поскольку оно не делает того, что вы на самом деле хотели):

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 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
group by id,m_name,cost;

Если ваш запрос слишком дорог таким образом, напишите Мне похвалу, тогда я улучшу его.

Один из редких случаев a CROSS JOIN применим:

WITH avgcost as (select round(avg(cost)) as Average from mobile)
SELECT id, m_name as "Mobile Name", cost as Price, Average,
cost-Average as Difference
FROM mobile cross join avgcost

Что приведет к:

ID  Mobile Name PRICE   AVERAGE DIFFERENCE
10  NOkia       100     123     -23
11  Samsung     150     123     27
12  Sony        120     123     -3
select pid, name, price as actualcost, 
       AVERAGE = (select AVG(price) from Part_Master), 
       price - (select AVG(price) as diff from Part_Master) AS COST_DIFF 
from   Part_Master

Comments

    Ничего не найдено.