MySQL计算yoy(逐年)数据

时间:2018-01-25 07:09:50

标签: mysql sql etl

我有一些月度粒度的MAU数据如下:
enter image description here

我想和你约会约会:

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,因此我没有窗口功能。 有没有更简单的方法来实现我想要的目标?

*数据类型:

Period                       | varchar(16)  
MAU                          | double  

1 个答案:

答案 0 :(得分:0)

理想情况下,定期数据将存储为日期或其组件,在本例中为年份和月份,作为单独的整数列。由于它们在此处一起表示为字符串,因此我们需要使用SUBSTRING来解析它们。解决方案背后的一般思想是我们需要使用一个"排列"的ON子句将表连接到自身。每行与之前一年的对应部分。

这应该是诀窍:

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

这是第二种方式,它的阅读稍微不那么清晰,但效率更高(特别是如果速度是一个问题,表格很大,并且它在句号上被编入索引)因为它避免了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

我希望这会有所帮助。