Getting previous row in MySQL

时间:2016-10-20 12:34:42

标签: mysql sql database

I'm stucked in a MySQL problem that I was not able to find a solution yet. I have the following query that brings to me the month-year and the number new users of each period in my platform:

select  
    u.period ,
    u.count_new as new_users
from 
(select DATE_FORMAT(u.registration_date,'%Y-%m') as period, count(distinct u.id) as count_new from users u group by DATE_FORMAT(u.registration_date,'%Y-%m')) u
order by period desc;

The result is the table:

period,new_users
2016-10,103699
2016-09,149001
2016-08,169841
2016-07,150672
2016-06,148920
2016-05,160206
2016-04,147715
2016-03,173394
2016-02,157743
2016-01,173013

So, I need to calculate for each month-year the difference between the period and the last month-year. I need a result table like this:

period,new_users
2016-10,calculate(103699 - 149001)
2016-09,calculate(149001- 169841)
2016-08,calculate(169841- 150672)
2016-07,So on...
2016-06,...
2016-05,...
2016-04,...
2016-03,...
2016-02,...
2016-01,...

Any ideas: =/

Thankss

2 个答案:

答案 0 :(得分:1)

您应该能够使用我发布的类似方法in another S/O question.您正处于良好的发展轨道。您有内部查询获取计数并按照您需要的最终方向进行排序。通过使用内联mysql变量,您可以拥有前一个记录值的保留列,然后将其用作下一个结果的计算基础,然后将该变量设置为要用于每个后续周期的新余额。 / p>

对SqlVars别名的JOIN没有任何" ON"条件,因为SqlVars无论如何只会返回一行,并且不会产生任何笛卡尔积。

select  
    u.period,
    if( @prevCount = -1, 0, u.count_new - @prevCount ) as new_users,
    @prevCount := new_users as HoldColumnForNextCycle    
   from 
      ( select 
              DATE_FORMAT(u.registration_date,'%Y-%m') as period, 
              count(distinct u.id) as count_new 
           from 
              users u 
           group by 
              DATE_FORMAT(u.registration_date,'%Y-%m') ) u
      JOIN ( select @prevCount := -1 ) as SqlVars
   order by 
      u.period desc;

你可能不得不玩一点,因为没有"开始"指向计数,因此任何排序方向的第一个条目可能看起来很奇怪。我正在启动" @ prevCount"变量为-1。因此,处理的第一个记录在" new_users"中得到新的用户数0。柱。然后,无论记录的新用户数是多少,我都会将@prevCount分配回作为所有后续记录的基础。是的,它是结果集中的一个额外列,可以忽略,但是需要。同样,它只是一个每行占位符,你可以在结果查询中看到它如何在每一行进展时获得它的价值......

答案 1 :(得分:0)

I would create a temp table with two columns and then fill it using a cursor that does something like this (don't remember the exact syntax - so this is just a pseudo-code):

@val = CURSOR.col2 - (select col2 from OriginalTable t2 where (t2.Period = (CURSOR.Period-1) ))) 

INSERT tmpTable (Period, NewUsers) Values ( CURSOR.Period, @val)
相关问题