sql >> データベース >  >> RDS >> Mysql

過去90日間のログインに基づいてアクティブユーザーをカウントします

    必要なすべての日付を含むカレンダーテーブルがある場合、このような問題は簡単に解決できます。このようなテーブルがない場合は、次のようなクエリで作成できます。

    create table `calendar` (
        `date` DATE NOT NULL,
        PRIMARY KEY (`date`)
    )  
        select DATE_ADD('1900-01-01',INTERVAL t4.c*10000 + t3.c*1000 + t2.c*100 + t1.c*10 + t0.c DAY) as `date`
        from 
        (select 0 c union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t0,
        (select 0 c union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t1,
        (select 0 c union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t2,
        (select 0 c union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t3,
        (select 0 c union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t4
    

    これにより、1900-01-01から2173-10-15(100K日)までの日付のテーブルが作成され、約2.5MBしか消費されません。必要に応じて調整できます。

    カレンダーテーブルを使用すると、3か月の範囲を取得できます:

    select 
        DATE_FORMAT(date_sub(c.date, INTERVAL 1 day), '%Y-%m') as month,
        date_sub(c.date, INTERVAL 3 month) as first_day,
        date_sub(c.date, INTERVAL 1 day)   as last_day
    from calendar c
    where day(c.date) = 1
      and c.date between '2015-02-01' and '2015-09-01'
    

    結果:

    | month   | first_day  | last_day   |
    | 2015-01 | 2014-11-01 | 2015-01-31 |
    | 2015-02 | 2014-12-01 | 2015-02-28 |
    | 2015-03 | 2015-01-01 | 2015-03-31 |
    | 2015-04 | 2015-02-01 | 2015-04-30 |
    | 2015-05 | 2015-03-01 | 2015-05-31 |
    | 2015-06 | 2015-04-01 | 2015-06-30 |
    | 2015-07 | 2015-05-01 | 2015-07-31 |
    | 2015-08 | 2015-06-01 | 2015-08-31 |
    

    本当に90日間隔のようなものを使用したい場合は、調整してください。

    これで、ログインテーブルとの単純な左結合で、必要なものを取得できます。

    select i.month as `Date`, count(distinct l.user_id) as `Active users`
    from (
        select 
            date_format(date_sub(c.date, interval 1 day), '%Y-%m') as month,
            date_sub(c.date, interval 3 month) as first_day,
            date_sub(c.date, interval 1 day)   as last_day
        from calendar c
        where day(c.date) = 1
          and c.date between '2015-02-01' and '2015-09-01'
    ) i
    left join login_table l on l.login_date between i.first_day and i.last_day
    group by i.month
    

    http://sqlfiddle.com/#!9/d1bb0/3



    1. .NET MySqlCommandでMySqlユーザー定義変数を使用することは可能ですか?

    2. ORA-00979:SQL を実行すると、GROUP BY 式ではありません

    3. MYSQL / PHPは、特定のアイテムに関連付けられている最も一般的なアイテムを検索します

    4. PostgreSQLMountainLionソケットの問題