Your group is what aggregates your average, and it is grouped throughout the table (I assume you did this to allow a choice for everything). Just move your avg to another subquery, delete the whole group, and that should solve it.
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)
, it is naturally grouped by the specified column (cost in this case), because this is what you request. I would advise reading more GROUP BY and aggregates until a better understanding of the concept. This should help you not just as a simple solution.
UPDATE:
The answer below is actually from David's answer. It uses analytic functions. Basically, what happens is that on every AVG call you tell the engine what to use for the function (in this case, nothing). A nice record of analytic functions can be found here and here and more with google on this.
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 variables, you can just as easily follow the answer below. I really prefer this for future maintainability / readability. The reason is that a variable with a good name can be very descriptive for future code readers, compared to an analytic function that requires a bit more work to read (especially if you don't understand the function).
In addition, this solution duplicates the same query twice, so you should save the average value in an SQL variable. Then you can change your statement to just use this global average
These are variables in SQL Server (you will have to adapt it for your own SQL instance)
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 much cleaner for future readers of your SQL, as well