Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 simple average problem or is it ?

Author  Topic 

Ajoo
Starting Member

12 Posts

Posted - 2013-11-24 : 12:40:12
Hi,

I have this table of Marks as shown below. All I need is to find the average Marks at various intervals of S.no. That is I need averages at every 3rd S.No. as shown.

S.No. Marks
1 ------ 5
2 ------ 5
3 ------ 6 1st Average Value here (16/3)
4 ------ 5
5 ------ 6
6 ------ 7 2nd Average Value here (18/3)
7 ------ 7
8 ------ 7
9 ------ 8 3rd Average Value here (22/3)
10 ----- 8
11 ----- 9
12 ----- 8 4th Average Value here (26/3)

So basically I need a new table which will have 4 average values for the table above. Of-course the table can be much bigger and the average values can be at any nth value of S.No.

I hope that someone can help me with this and i also hope it has a simple solution to it.

Thanks in advance to all gurus.

bitsmed
Aged Yak Warrior

545 Posts

Posted - 2013-11-24 : 17:25:50
Assuming S.No. has no gaps, this ought to do it:

select *
from (select max([S.No.]) as [S.No.]
,cast(round(avg(Marks*1.0),0) as int) as AvgMarks
from Marks
group by ([S.No.]-1)/3
) as a
where [S.No.]%3=0

Replace the number in red, with interval number you want
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2013-11-25 : 00:08:37
[code]
SELECT MIN(Sno) AS StartVal,MAX(Sno) AS EndVal,AVG(Marks * 1.0)
FROM (SELECT ROW_NUMBER() OVER (ORDER BY Sno) AS RN,* FROM Table)t
GROUP BY (RN-1)/3
[/code]

or if sql 2012

[code]
SELECT AvgVal
FROM
(
SELECT AVG(Marks * 1.0) OVER (ORDER BY SNo ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) AS AvgVal,
ROW_NUMBER() OVER (ORDER BY SNo) AS Seq
FROM Table
)t
WHERE Seq % 3 = 0
[/code]

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/
https://www.facebook.com/VmBlogs
Go to Top of Page

Ajoo
Starting Member

12 Posts

Posted - 2013-11-25 : 03:21:55
Hi guys,
Thanks very much for the reply. I have tried bitsmed's solution. The query did not work directly ( maybe cos of the version of SQL) till i made a few changes and then it did. Here are the changes that I made:
select *
from (select max(sno) as sno
,cast(round(avg(Marks*1.0),0) as unsigned) as AvgMarks
from Marks
group by sno-1/3 // I even tried sno/3 and that gave the same result
) as a
where sno%3=0

AND the query executed BUT it did not take the 3 entries and found their averages. Instead it just gave me the 3rd, 6th, 9th and 12 value present in the marks table. So while the query executed the result is wrong. Kindly modify it to calcuate the averages correctly. Thanks. Now I am going to try out Visakh's solution and will revert. Thanks again.
Go to Top of Page

Ajoo
Starting Member

12 Posts

Posted - 2013-11-25 : 05:22:23
Hi Gurus,

Back again, I tried using visakh's solution but i get the error "#1305 - FUNCTION ROW_NUMBER does not exist". I must admit I find Visakh's code very new cos I have not seen these sort of instructions in mysql. Maybe if Visakh / any gure can guide me some, i'll be able to execute the pieces of code as listed by Visakh.

The second bit of code also gave the following error : "#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(ORDER BY SNo ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) AS AvgVal, ROW_NUMBER()' at line 4".
Thanks guys. Looking forward more replies on this soon. Thanks loads.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2013-11-25 : 05:28:14
quote:
Originally posted by Ajoo

Hi Gurus,

Back again, I tried using visakh's solution but i get the error "#1305 - FUNCTION ROW_NUMBER does not exist". I must admit I find Visakh's code very new cos I have not seen these sort of instructions in mysql. Maybe if Visakh / any gure can guide me some, i'll be able to execute the pieces of code as listed by Visakh.

The second bit of code also gave the following error : "#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(ORDER BY SNo ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) AS AvgVal, ROW_NUMBER()' at line 4".
Thanks guys. Looking forward more replies on this soon. Thanks loads.


If you're using MySQL you're in the wrong forum
This is MS SQL Server forum and we deal with T-SQL. there're not many experts on MySQL here. So you may be better off trying this in some MySQL forums.

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/
https://www.facebook.com/VmBlogs
Go to Top of Page

Ajoo
Starting Member

12 Posts

Posted - 2013-11-25 : 07:01:48
Hi Visakh, Yes thank you. I thought that might be the case and so I mentioned Mysql. However the solution by bitsmed is almost what i am looking for and its very near working. Maybe you or bitsmed himself or anyone can improve it and tweak it just some bit to make it work. I would be eternally grateful. Thanks loads.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2013-11-25 : 07:10:01
as far as I see the only change that may be needed in your version is this.


select *
from (select max(sno) as sno
,cast(round(avg(Marks*1.0),0) as unsigned) as AvgMarks
from Marks
group by (sno-1)/3
) as a
where sno%3=0


and i think it should work fine

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/
https://www.facebook.com/VmBlogs
Go to Top of Page

Ajoo
Starting Member

12 Posts

Posted - 2013-11-25 : 11:15:13
Hi all ! Visakh that's the 100% exactly copy of what i wrote in my post 2 replies ago. This one executes but fails to Average in groups of 3 and gives only the value at positions like at row 3, 6, 9 & 12. Kindly look into it. Here is actual run of the code you just gave on the Marks table modified below:

Marks Table
sno Marks
1 5
2 5
3 6
4 6
5 7
6 6
7 7
8 6
9 8
10 7
11 7
12 8
13 9
14 10
15 11

The Result :

sno AvgMarks
3 6
6 6
9 8
12 8
15 11

As can be seen, there is no average but the actual marks value at those ( 3rd, 6th, 9th ..rows) positions.
Kindly help solve this. Thanks all.

Go to Top of Page

bitsmed
Aged Yak Warrior

545 Posts

Posted - 2013-11-25 : 12:19:35
quote:
Originally posted by Ajoo

Hi all ! Visakh that's the 100% exactly copy of what i wrote in my post 2 replies ago. This one executes but fails to Average in groups of 3 and gives only the value at positions like at row 3, 6, 9 & 12. Kindly look into it. Here is actual run of the code you just gave on the Marks table modified below:

Marks Table
sno Marks
1 5
2 5
3 6
4 6
5 7
6 6
7 7
8 6
9 8
10 7
11 7
12 8
13 9
14 10
15 11

The Result :

sno AvgMarks
3 6
6 6
9 8
12 8
15 11

As can be seen, there is no average but the actual marks value at those ( 3rd, 6th, 9th ..rows) positions.
Kindly help solve this. Thanks all.




Try this:

select *
from (select max(sno) as sno
,round(avg(Marks),0) as AvgMarks
from Marks
group by floor((sno-1)/3)
) as a
where sno%3=0

The difference here is I'm floor'ing the calculated "group by" value, as mysql apparently returns a float value.
Again, replace the number in red, with interval number you want.
Go to Top of Page

Ajoo
Starting Member

12 Posts

Posted - 2013-11-25 : 12:42:49
Hey ! wow ! worked like a charm. Thanks loads. Gurus are great !! Just one more request if you can explain exactly how it works, this query. I have been trying to disect it and see but still cannot completely get it. How, for eg., is it able to pick the 3 consecutive values and average them. Maybe if you create an intermediate field on which it is getting grouped, I would be able to understand it better. I know what floor(sno-1)/3 AND sno%3 = 0 do but the logic is unclear. Kindly explain. Thanks again.
Go to Top of Page

bitsmed
Aged Yak Warrior

545 Posts

Posted - 2013-11-25 : 13:08:02
quote:
Originally posted by Ajoo

Hey ! wow ! worked like a charm. Thanks loads. Gurus are great !! Just one more request if you can explain exactly how it works, this query. I have been trying to disect it and see but still cannot completely get it. How, for eg., is it able to pick the 3 consecutive values and average them. Maybe if you create an intermediate field on which it is getting grouped, I would be able to understand it better. I know what floor(sno-1)/3 AND sno%3 = 0 do but the logic is unclear. Kindly explain. Thanks again.


First it calculates the "group by" value:

sno mark groupvalue
1 5 (1-1)/3=0
2 5 (2-1)/3=0
3 6 (3-1)/3=0
4 6 (4-1)/3=1
5 7 (5-1)/3=1
6 6 (6-1)/3=1
7 7 (7-1)/3=2
8 6 (8-1)/3=2
9 8 (9-1)/3=2
10 7 (10-1)/3=3
11 7 (11-1)/3=3
12 8 (12-1)/3=3
13 9 (13-1)/3=4
14 10 (14-1)/3=4
15 11 (15-1)/3=4

Then it's a simple matter of grouping this value, and return max sno and average mark:

maxsno avgmark
3 (5+5+6)/3=5
6 (6+7+6)/3=6
9 (7+6+8)/3=7
12 (7+7+8)/3=7
15 (9+10+11)/3=10

Now this is wrapped as as subselect, to be able to disgard rows, not divideable by 3.
So had you left out row 15, you would receive:

maxsno avgmark
3 (5+5+6)/3=5
6 (6+7+6)/3=6
9 (7+6+8)/3=7
12 (7+7+8)/3=7
14 (9+10)/3=9

And as you "only" wanted the calculare average, every 3rd row, I discard the last one.

Hope this clarifies things.
Go to Top of Page

Ajoo
Starting Member

12 Posts

Posted - 2013-11-25 : 13:36:10
Hi bitsmed, thanks loads for this explanation. I have just gone thru it. Now i'll try and implement this in phpMyAdmin and see for myself what you have explained. If the need arises I'll bother you again. Thanks loads for the solution and explanation. You guys rock !
Go to Top of Page
   

- Advertisement -