MySQL 计算同比(同比)数据

MySQL calculate yoy (year-over-year) data

我有一些每月粒度的 MAU 数据,如下所示:

我想获得像这样的 yoy 日期:

2016-04 yoy MAU = (2016-04 MAU - 2015-04 MAU)/2015-04 MAU  
2016-03 yoy MAU = (2016-03 MAU - 2015-03 MAU)/2015-03 MAU
...

我正在使用 MySQL,所以我没有 window 功能。 有没有更简单的方法来实现我想要的?

*数据类型:

Period                       | varchar(16)  
MAU                          | double  

理想情况下,周期性数据将存储为日期或其组成部分,在本例中,年和月作为单独的整数列。由于它们在这里一起表示为一个字符串,我们需要使用 SUBSTRING 来解析它们。解决方案背后的总体思路是,我们需要使用一个 ON 子句将 table 连接到自身,该子句 "lines up" 每行与其一年前的对应行。

这应该可以解决问题:

select a.Period, a.MAU, b.Period as prior_year, b.MAU as prior_mau,
        (a.MAU - b.MAU) / b.MAU as yoy
    from tbl1 a
    left join tbl1 b on 
        cast(substring(b.Period, 1, 4) as int) = 
        cast(substring(a.Period, 1, 4) as int) - 1 
        and substring(b.Period, 5, 3) = substring(a.Period, 5, 3)   
    order by a.Period asc

这是第二种方式,读起来不太清楚,但效率更高(尤其是在速度有问题的情况下,table 很大,并且在 Period 上建立索引),因为它避免了在 where 中的计算子句(至少在一侧):

select a.Period, a.MAU, b.Period as prior_year, b.MAU as prior_mau,
        (a.MAU - b.MAU) / b.MAU as yoy
    from tbl1 a
    left join tbl1 b on 
        a.Period 
        = cast(cast(substring(b.Period, 1, 4) as int) - 1 as varchar(4)) 
        + substring(b.Period, 5, 3)   
    order by a.Period asc

希望对您有所帮助。