如何计算mysql中的一系列结果

时间:2018-02-08 02:30:00

标签: mysql

我现在有一个记录表,我必须统计每个月的结果。

这是一个测试表

+----+------+----------+----------+------+
| 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)

时间列表示月份(实际为时间戳)。

我需要统计那些grade1> = 1&&amp ;;每个等级2> = 1

所以,我想得到像这样的结果

+----+------+----------+----------+----------+----------+------+
| 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)

sql的假代码看起来像这样:

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

事实上,我已经完成了,但是使用临时表如下:

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

但是这个sql太长了。这个测试表只是一个简单的版本。在实际情况下,我打印了我的sql,并在chrome中占用了两个屏幕。所以我正在寻求一种更简单的方法来完成它

1 个答案:

答案 0 :(得分:1)

你的原始版本几乎就在那里。您需要case,而sum()更合适:

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