[英]How to calculate average of a column and then include it in a select query in oracle?
My table is-- 我的桌子是 -
create table mobile
(
id integer,
m_name varchar(20),
cost integer
)
and the values are -- 而价值观是 -
insert into mobile values(10,'NOkia',100);
insert into mobile values(11,'Samsung',150);
insert into mobile values(12,'Sony',120);
I know how to calculate average on column cost, my code is-- 我知道如何计算柱成本的平均值,我的代码是 -
select avg(cost) from mobile;
and the result is 123 结果是123
But i want to calculate average and then also show the difference.I was able to this but, I am not able to add avg column in the select query-- 但我想计算平均值,然后也显示差异。我能够这样但但是,我无法在选择查询中添加avg列 -
My code is --- 我的代码是---
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;
and the output is -- 输出是 -
id Mobile Name Price Average Difference
10 Nokia 100 100 -23
11 Samsung 150 150 27
12 Sony 120 120 -3
what I wants is to correct this average column.. I wants this--- 我想要的是纠正这个平均列..我想要这个---
id Mobile Name Price Average Difference
10 Nokia 100 123 -23
11 Samsung 150 123 27
12 Sony 120 123 -3
please help... 请帮忙...
Since you're using Oracle, you should be able to use AVG() as an analytic (window) function: 由于您使用的是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
No need for subqueries or GROUP BY. 不需要子查询或GROUP BY。
Your group by is what aggregates your average, and it is grouping by the whole table (I am assuming you did this to allow the select for everything) Just move your avg into another subquery, remove the overarching group by and that should solve it. 你的分组是汇总你的平均值,它是整个表的分组(我假设你这样做是为了允许选择所有的东西)只需将你的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;
When you run the basic SELECT AVG(cost)
statement it is naturally grouping by the column specified (cost in this case) as that is what you are requesting. 当您运行基本的
SELECT AVG(cost)
语句时,它自然按指定的列(在这种情况下为SELECT AVG(cost)
分组,因为这是您请求的内容。 I would suggest reading up more on GROUP BY and aggregates to get a better grasp on the concept. 我建议阅读更多关于GROUP BY和聚合的内容 ,以便更好地掌握这个概念。 That should help you more than just a simple solution.
这应该不仅仅是一个简单的解决方案。
UPDATE: 更新:
The answer below is actually from David's answer. 下面的答案实际上来自大卫的回答。 It makes use the analytical functions.
它利用了分析功能。 Basically, what is happening is that on each AVG call, you are telling the engine what to use for the function (in this case, nothing).
基本上,正在发生的事情是,在每个AVG调用中,您告诉引擎该功能使用什么(在这种情况下,什么都没有)。 A decent writeup on analytical functions can be found here and here and more with a google on the matter.
关于分析函数的一个体面的文章可以在这里和这里找到,还有更多关于这个问题的谷歌。
SELECT id, m_name AS "Mobile Name" cost AS Price, AVG(cost) OVER( ) AS Average,
cost - AVG(cost) OVER ( ) AS Difference
FROM mobile
However, if your SQL engine allows for variables, you could just as easily do the below answer. 但是,如果您的SQL引擎允许变量,您可以轻松地执行以下答案。 I actually prefer this for future maintainability/readability.
我实际上更喜欢这个用于将来的可维护性/可读性。 The reason is that a variable with a good name can be very descriptive to future readers of the code, versus an analytical function that does require a little bit more work to read (especially if you do not understand the over function).
原因是具有良好名称的变量可以非常描述代码的未来读者,而不是需要更多工作来阅读的分析函数(特别是如果您不理解过度函数)。
Also, this solution duplicates the same query twice, so it might be worth storing your average in a SQL variable. 此外,此解决方案复制相同的查询两次,因此可能值得将您的平均值存储在SQL变量中。 Then you ca change your statement to simply use that global average
然后你可以改变你的陈述,只需使用那个全局平均值
This is variables in SQL-Server (you will have to adapt it for your own instance of SQL) 这是SQL-Server中的变量(您必须根据自己的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;
This solution will read a lot cleaner to future readers of your SQL, too 此解决方案也将为您的SQL的未来读者提供更多清洁
The simplest change is to change avg(cost) as Average
to (select avg(cost) from mobile) as Average
. 最简单的变化是将
avg(cost) as Average
改为(select avg(cost) from mobile) as Average
。 This also means that you won't need the GROUP BY
clause anymore (since it doesn't do what you actually wanted): 这也意味着您将不再需要
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 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
try 尝试
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;
if your query is too expensive that way drop me a commend then I'll improve it. 如果您的查询太昂贵,那么请给我一个推荐,然后我会改进它。
One of the rare times a CROSS JOIN
is applicable: 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
Which will result in: 这将导致:
ID Mobile Name PRICE AVERAGE DIFFERENCE
10 NOkia 100 123 -23
11 Samsung 150 123 27
12 Sony 120 123 -3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.