Reputation: 1175
l have a record table now, and l must to statistics the result of every month.
here is a test table
+----+------+----------+----------+------+
| id | name | grade1 | grade2 | time |
+----+------+----------+----------+------+
| 1 | a | 1 | 1 | 1 |
| 2 | a | 0 | 1 | 1 |
| 3 | a | 1 | 2 | 2 |
| 4 | b | 1 | 2 | 2 |
| 5 | a | 1 | 1 | 2 |
+----+------+----------+----------+------+
5 rows in set (0.01 sec)
time column means month(the actual is timestamp).
l need to statistics total number those grade1 >=1 && grade2 >=1 in every month
So, l want to get the result like this
+----+------+----------+----------+----------+----------+------+
| id | name | grade1_m1| grade2_m1| grade1_m2| grade2_m2| time |
+----+------+----------+----------+----------+----------+------+
| 13 | a | 1 | 2 | null | null | 1 |
| 14 | a | null | null | 2 | 2 | 2 |
| 15 | b | null | null | 1 | 1 | 2 |
+----+------+----------+----------+----------+----------+------+
3 rows in set (0.00 sec)
fake code of sql seem like this:
select
count(grade1 where time=1 and grade1 >= 1) as grade1_m1,
count(grade2 where time=1 and grade2 >= 1) as grade1_m1,
count(grade1 where time=2 and grade1 >= 1) as grade1_m2,
count(grade2 where time=2 and grade2 >= 1) as grade1_m2,
-- ... 12 months' statistics
from test
group by name
In the fact, l done it, but with temporary table like follow:
select
count(if(m1.grade1>=1, 1, null)) as grade1_m1,
count(if(m1.grade2>=1, 1, null)) as grade2_m1,
count(if(m2.grade1>=1, 1, null)) as grade1_m2,
count(if(m2.grade2>=1, 1, null)) as grade2_m2,
-- ...
from test
left join
(select * from test where time = 1) as m1
on m1.id = test.id
left join
(select * from test where time = 1) as m2
on m2.id = test.id
-- ...
group by name
But this sql is toooooooo long. this test table is just a simple version. Under real situation, l printed my sql and that took up two screens in chrome. So l am seeking a more simple way to complete it
Upvotes: 0
Views: 41
Reputation: 1270081
You're original version is almost there. You need case
and sum()
is more appropriate:
select name,
sum(case when time=1 and grade1 >= 1 then grade1 end) as grade1_m1,
sum(case when time=1 and grade2 >= 1 then grade2 end) as grade2_m1,
sum(case when time=2 and grade1 >= 1 then grade1 end) as grade1_m2,
sum(case time=2 and grade2 >= 1 then grade2 end) as grade2_m2,
-- ... 12 months' statistics
from test
group by name
Upvotes: 1