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 ------ 55 ------ 66 ------ 7 2nd Average Value here (18/3)7 ------ 78 ------ 79 ------ 8 3rd Average Value here (22/3)10 ----- 811 ----- 912 ----- 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 |
 |
|
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)tGROUP BY (RN-1)/3[/code]or if sql 2012[code]SELECT AvgValFROM(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 SeqFROM Table)tWHERE Seq % 3 = 0[/code]------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/https://www.facebook.com/VmBlogs |
 |
|
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. |
 |
|
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. |
 |
|
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 MVPhttp://visakhm.blogspot.com/https://www.facebook.com/VmBlogs |
 |
|
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. |
 |
|
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 AvgMarksfrom Marksgroup by (sno-1)/3 ) as awhere sno%3=0 and i think it should work fine------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/https://www.facebook.com/VmBlogs |
 |
|
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 Tablesno Marks1 52 53 64 65 76 67 78 69 810 711 712 813 914 1015 11The Result :sno AvgMarks3 66 69 812 815 11As 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. |
 |
|
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 Tablesno Marks1 52 53 64 65 76 67 78 69 810 711 712 813 914 1015 11The Result :sno AvgMarks3 66 69 812 815 11As 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. |
 |
|
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. |
 |
|
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. |
 |
|
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 ! |
 |
|
|