mysql cumulative sum of same field value - mysql

I have sample data with table name catdog
| No | id | data |
1 1 4000
2 2 300
3 3 100
4 1 400
5 2 30
6 3 10
7 1 40
8 2 3
9 3 1
I want the result like this:
| No | id | data | totaldata |
1 1 4000 4000
2 2 300 300
3 3 100 100
4 1 400 4400 --------> 4000 + 400 on id
5 2 30 330 --------> 300 + 30 on id
6 3 10 110 --------> 100 + 10 on id
7 1 40 4440 --------> 4000 + 400 + 40 on id
8 2 3 333 --------> 300 + 30 + 1 on id
9 3 1 111 --------> 100 + 10 + 1 on id
Sum if field No is same.
How to write a mysql query for my case?
very very thank you so much GurV

Try this:
select no, id, data, c_data from (
select t1.*,
#data := case when #id = id then #data + data else data end c_data,
#id := id
from
(select * from catdog
order by id, No) t1
cross join (select #id := -1, #data := 0) t2) t
order by no;
It uses user defined variables to keep track of sum till now for each id

Related

Mysql rank with join table, result not true

I have 2 table name table 'hasil' and table 'kat_soal' to join and give rank on each 'KatID' field on 'hasil' table..
here is my hasil table :
HasilID KatID UserID JBenar JSalah Nilai
15 1 1000 2 1 66.66666666666666
16 3 1000 2 0 100
17 1 1001 1 2 33.33333333333333
18 3 1001 1 1 50
19 1 1002 3 0 90
20 3 1002 2 0 80
and there is my kat_soal table
KatID Kategori Lama
1 IPA 30
2 IPS 30
3 Matematika 30
4 Bahasa Indonesia 20
5 Bahasa Inggris 20
this my query generate rank:
SELECT a.KatID,a.UserID,b.Kategori,c.Nama,a.JBenar,a.JSalah,ROUND(a.Nilai,2) as Nilai,
FIND_IN_SET( a.Nilai, l.list) AS rank
from hasil a
JOIN kat_soal b
ON a.KatID = b.KatID
JOIN datauser c
ON a.UserID=c.UserID
CROSS JOIN
(SELECT GROUP_CONCAT( a2.Nilai ORDER BY a2.Nilai DESC ) as list
FROM hasil a2) l
WHERE a.KatID='1'
ORDER BY a.Nilai DESC;
my result
//FOR KatID=1
KatID UserID Kategori Nama JBenar JSalah Nilai rank
1 1002 IPA ratam 3 0 90.00 2
1 1000 IPA Tarsan 2 1 66.67 4
1 1001 IPA wisnu 1 2 33.33 6
//FOR KatID=3
3 1000 Matematika Tarsan 2 0 100.00 1
3 1002 Matematika ratam 2 0 80.00 3
3 1001 Matematika wisnu 1 1 50.00 5
My Expected Result
//FOR KatID=1
KatID UserID Kategori Nama JBenar JSalah Nilai rank
1 1002 IPA ratam 3 0 90.00 1
1 1000 IPA Tarsan 2 1 66.67 2
1 1001 IPA wisnu 1 2 33.33 3
//FOR KatID=3
3 1000 Matematika Tarsan 2 0 100.00 1
3 1002 Matematika ratam 2 0 80.00 2
3 1001 Matematika wisnu 1 1 50.00 3
anyone can help me ?
Good example to solve the issue is by looking at: http://www.fromdual.com/ranking-mysql-results .
You are making this a bit complicated: First You take the value, making the value a string, then "finding position in string".
From the example it should be completely ok if it is done as (untested):
SET #rank=0;
SELECT a.KatID,a.UserID,b.Kategori,c.Nama,a.JBenar,a.JSalah,ROUND(a.Nilai,2) as Nilai,
#rank:=#rank+1 AS rank
from hasil a
JOIN kat_soal b
ON a.KatID = b.KatID
JOIN datauser c
ON a.UserID=c.UserID
WHERE a.KatID='1'
ORDER BY rank;
EDIT: Changed ordering - You are expecting to by ordered by rank in the final.
Below is the script without using table datauser for any1 to test:
SET #rank=0;
SELECT a.KatID,a.UserID,b.Kategori,a.JBenar,a.JSalah,ROUND(a.Nilai,2) as Nilai,
#rank:=#rank+1 AS rank
from hasil a
JOIN kat_soal b
ON a.KatID = b.KatID
WHERE a.KatID='1'
ORDER BY rank;

Simple ordering in sql

I have table with the following data
id | name | passed | rank | Class
1 abc y 1 1
2 xyz y 1 2
3 lmn n 54 1
4 opq n 54 2
5 rst y 2 1
6 uvw y 2 2
What sql query can give me the following result:
id | name | passed | rank | Class
1 abc y 1 1
2 rst y 2 1
4 def y 55 1
3 lmn n 54 1
5 xyz y 1 2
6 uvw y 2 2
7 opq n 54 2
Group by class first all students with class = 1 , then 2 and so on.
the passsed == n should always come by the end and if there are 2 students with passed == n they should be ordered rank wise.
rest of the students with passed == y should be orders rank wise.
Tried:
select id, name, passed, rank, class
from students
ORDER BY passed DESC, rank
This gives :
id | name | passed | rank | Class
1 abc y 1 1
4 xyz y 1 2
2 rst y 2 1
5 uvw y 2 2
3 def y 55 1
6 opq n 54 2
3 lmn n 54 1
So I get passed==n at bottom and rest ordered as per rank.I think the only thing remaining is group by class.
Can't you just add the order or class first?
select id,
name,
passed,
rank,
class
from students
ORDER BY `Class`,
passed DESC,
rank

How to calulate SUM previous and current row value in MySQL table?

My table is "Activity_table", which have 4 columns. How can I create a function, which SUM each Peroson 2 previous and current activities?
My Activity_table
ID PID AID Act
1 1 1 12
2 1 2 32
3 2 1 5
4 1 3 21
5 2 2 12
6 2 3 19
7 1 4 11
8 2 4 6
PID-PersonID; AID-ActivitieID; Act-Activitie Value
My target:
ID PID AID Act SUM
1 1 1 12 12
2 1 2 32 44
3 2 1 5 5
4 1 3 21 65
5 2 2 12 17
6 2 3 19 36
7 1 4 11 64
8 2 4 6 37
Sum1=12; Sum2=32+12; Sum3=5; Sum4=21+32+12; Sum5=12+5; Sum6=19+12+5; Sum7=11+21+32; Sum8=6+19+12; Thank you,
To use the two previous and the current row,
SELECT ID,PID,AID,Act,
(SELECT SUM(Act)
FROM Activity_table
WHERE ID <= a.ID
AND ID >= a.ID - 2
AND PID = a.PID)
FROM Activity_table a;
You are taking the SUM according to the PID right? Then the last two rows of your target should be modified as,
7 1 4 11 **76**
8 2 4 6 **42**
The most flexible query is for your requirement is,
SELECT ID,PID,AID,Act,
(SELECT SUM(Act)
FROM Activity_table
WHERE ID <= a.ID
AND PID = a.PID)
FROM Activity_table a;
Then if you need only the flow of SUM of a particular PID, you can change it like this,
SELECT ID,PID,AID,Act,
(SELECT SUM(Act)
FROM Activity_table
WHERE ID <= a.ID
AND PID = a.PID)
FROM Activity_table a
WHERE PID = 2;
Result:
ID PID AID Act SUM
3 2 1 5 5
5 2 2 12 17
6 2 3 19 36
8 2 4 6 42
Sorry for the previous wrong Answers (deleted).
This produces the correct answer based on your example:
SET #LastPID = 0, #Act1 = 0,#Act2 = 0,#Act3 = 0;
SELECT ID,PID,AID,Act,`SUM` FROM
(
SELECT ID,PID,AID,Act,#Act3 := IF(#LastPID != PID, 0,#Act2),#Act2 := IF(#LastPID != PID, 0,#Act1), #Act1 := Act, #Act1 + #Act2 + #Act3 `SUM`, #LastPID := PID
FROM Activity_table
ORDER BY PID,ID
) sm
ORDER BY ID
;

Select according to rows increments

I have a MySQL database like this one :
ID | Twin | Tloss
0 | 300 | 250 #first entry
1 | 301 | 250 #win; score 1 - 0
2 | 302 | 250 #win; score 2 - 0
3 | 302 | 251 #lose: score 2 - 1
4 | 303 | 251 #win; score 3 - 1
5 | 304 | 251 #end of match1 : Win 4 - 1
6 | 304 | 252 #lose; score 0 - 1
7 | 304 | 253 #lose; score 0 - 2
8 | 304 | 254 #lose; score 0 - 3
9 | 304 | 255 #end of match2 : Lose 0 - 4
10 | 304 | 256 #lose; score 0 - 1
11 | 305 | 253 #win; score 1 - 1
12 | 306 | 254 #win; score 2 - 1
13 | 306 | 255 #lose; score 2 - 2
14 | 307 | 255 #win; score 3 - 2
15 | 307 | 256 #end of match3 : Draw 3 - 3
....
I want to select all the ID corresponding to the match number "n",
considering a match is ended as soon as he wins 4 times or loses 4 times, draw is possible as the maximum number of round per match is 6.
I use SQL a lot since 1 months but I'm really lost on this one.
Could someone help me ?
Thanking you in advance,
I am assuming that some of the data above is broken (records 11-15, field tloss; record 5 should be Win 4 - 1). I also don't know what are the numbers 300 and 250 and how they change in the table. With these assumptions, this untested SQL might be want you want:
(revised after feedback from GordonLinoff)
SELECT #matchno := #matchno + 1 AS matchno
FROM (SELECT #matchno := 0) mn,
(SELECT ID, Twin, Tloss,
IF((Twin - #twin) = 4
OR (Tloss - #tloss) = 4
OR ((Twin - #twin) = 3 AND (Tloss - #tloss) = 3),
#twin := Twin AND #tloss := Tloss,
0)
FROM matches, (SELECT #twin := 300, #tloss := 250) AS base
WHERE (Twin - #twin) = 4
OR (Tloss - #tloss) = 4
OR ((Twin - #twin) = 3 AND (Tloss - #tloss) = 3)
ORDER BY ID
) endmatches

mysql pivot query and rank Query

I Have a marksheet table like:
ID STUDENT_ID Branch_id Class_id Exam_id Subject_id Numbers Date
1 653 5 1 1 8 60 2012-01-01
2 653 5 1 1 9 40 2012-01-01
3 653 5 1 1 10 80 2012-01-01
4 653 5 1 1 11 50 2012-01-01
5 653 5 1 1 12 65 2012-01-01
6 653 5 1 1 13 33 2012-01-01
7 653 5 1 1 15 86 2012-01-01
8 222 5 1 1 8 100 2012-01-01
9 222 5 1 1 9 80 2012-01-01
10 222 5 1 1 10 92 2012-01-01
11 222 5 1 1 11 50 2012-01-01
12 222 5 1 1 12 65 2012-01-01
13 222 5 1 1 13 33 2012-01-01
7 222 5 1 1 15 86 2012-01-01
I want to get rank I got answer by this question
Also when I fetched all class result I use pivot query:
SELECT stu_id, sum(numbers) AS total, branch_id, depart_id, class_id,
SUM( IF( subject_id =1, numbers, 0 ) ) AS MAth,
SUM( IF( subject_id =2, numbers, 0 ) ) AS Eng,
SUM( IF( subject_id =3, numbers, 0 ) ) AS Science
FROM marksheet where branch_id = 1 AND depart_id = 1
AND class_id = 1 GROUP BY stu_id ORDER BY total DESC
I want to get rank in my class query (pivot query)? And I want to count how many students on first position and how many on second and third?
Required Data sample:
ID Name Math English Science Total Percent Position Rank
Any one help?
I think what you need to do is create a second table with grade boundaries that are being referenced so for instance :
ID grade start_boundry end_boundry
1 A 60 100
ect..
then create a join between the tables and then do a WHERE statement between the Numbers and the start/ end boundries
so ->
SELECT grade FROM boundries_table RIGHT JOIN sudent_table
WHERE boundries_table.start_boundry < student_table.numbers
AND boundries_table.end_boundry > student_table.numbers
i think that should work if my MySQL memory serves, just modify the table to how you need it to run and it should work for how you need it.