MySQL: Count of records with consecutive months

后端 未结 2 499
轮回少年
轮回少年 2021-01-12 22:56

I\'ve searched around for this, but all the similar questions and answers are just different enough not to work.

I have a table with the following fields: person, th

相关标签:
2条回答
  • 2021-01-12 23:26

    I used this StackOverflow answer for guidance (Check for x consecutive days - given timestamps in database)

    SELECT a.person, COUNT(1) AS consecutive_months
    FROM
    (
    
      SELECT a.person, IF(b.YearMonth IS NULL, @val:=@val+1, @val) AS consec_set
      FROM (
        SELECT DISTINCT person, EXTRACT(YEAR_MONTH from purdate) as YearMonth from records
        ) a
      CROSS JOIN (SELECT @val:=0) var_init
      LEFT JOIN (SELECT DISTINCT person, EXTRACT(YEAR_MONTH from purdate) as YearMonth from records) b ON
          a.person = b.person AND
          a.YearMonth = b.YearMonth + 1
       ) a
    GROUP BY a.consec_set
    HAVING COUNT(1) >= 2    
    

    Here is the SQLFiddle - http://sqlfiddle.com/#!2/cc5c3/55

    0 讨论(0)
  • 2021-01-12 23:40

    You can do this in MySQL using variables (or very complicated correlated subqueries). In other databases, you would use window/analytic functions.

    The logic is:

    1. Get one row per month and person with a purchase.
    2. Use variables to assign each group of consecutive months a "grouping" value.
    3. Aggregate by the person and the "grouping" value.

    Here is a query that has been tested on your SQL Fiddle:

    select person, count(*) as numMonths
    from (select person, ym, @ym, @person,
                 if(@person = person and @ym = ym - 1, @grp, @grp := @grp + 1) as grp,
                 @person := person,
                 @ym := ym
          from (select distinct person, year(purdate)*12+month(purdate) as ym
                from records r
               ) r cross join
               (select @person := '', @ym := 0, @grp := 0) const
          order by 1, 2
         ) pym
    group by person, grp;
    
    0 讨论(0)
提交回复
热议问题