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

ログからの毎日の毎週のアクティブユーザー

    「週平均ユーザー」数(私の仕様の理解によると、「毎日、その日と過去6日間に見られた個別のuser_idの数」)を取得するには、以下の行に沿ってクエリを実行します。使用することができます。 (クエリは「1日平均ユーザー」数も返します。

    SELECT d.day
         , COUNT(DISTINCT u.user_id) AS wau
         , COUNT(DISTINCT IF(u.day=d.day,u.user_id,NULL)) AS dau
      FROM ( SELECT FLOOR(k.ts/86400) AS `day`
               FROM `log` k
              GROUP BY `day`
           ) d
      JOIN ( SELECT FLOOR(l.ts/86400) AS `day`
                  , l.user_id
               FROM `log` l
              GROUP BY `day`, l.user_id
           ) u
        ON u.day <= d.day
       AND u.day > d.day - 7
     GROUP BY d.day
     ORDER BY d.day
    

    (私はまだこれのテストを実行していませんが、後で実行し、修正が必要な場合はこのステートメントを更新します。)

    このクエリは、特定の日のユーザーのリストに参加しています(uから) rowsource)、ログテーブルからの一連の日(d rowsource)。結合述語(ON句)に表示される文字通りの「7」に注意してください。これにより、ユーザーリストが過去6日間に「一致」します。

    これを拡張して、たとえばSELECTリストに別の式を追加することにより、過去3日間の個別のユーザー数を取得することもできます。

         , COUNT(DISTINCT IF(u.day<=d.day AND u.day>d.day-3,u.user_id,NULL)) AS 3day
    

    そのリテラル「7」は、より広い範囲を取得するために増やすことができます。そして、上記の式のリテラル3は、任意の日数を取得するように変更できます...前日の行が十分にあることを確認する必要があります(dから) )uから各行に結合 。

    パフォーマンスに関する注意:インラインビュー(またはMySQLでは派生テーブルと呼ばれる)が原因で、これらのインラインビューの結果セットを中間のMyISAMテーブルにマテリアライズする必要があるため、このクエリはそれほど高速ではない可能性があります。

    uとしてエイリアスされたインラインビュー 最適ではない可能性があります。ログテーブルに直接参加する方が速い場合があります。特定の日のユーザーの一意のリストを取得するという観点から考えていました。これは、インラインビューでのクエリによって得られたものです。何が起こっているのかを概念化するのは私にとって簡単でした。そして、同じユーザーが何百人も1日入力した場合、インラインビューは、他の日に参加する前に、重複の全体を取り除くと考えていました。WHERE句を使用して、日数を制限します。戻ってくるのはu内に追加するのが最適です およびd インラインビュー。 (d インラインビューには、6日前に追加する必要があります。)

    別の注意点として、ts列がTIMESTAMPデータ型の場合、DATE(ts)を使用する傾向があります。 日付部分を抽出する式。ただし、整数ではなく、結果セットにDATEデータ型が返されます。これは、指定した結果セットとは異なります。)

    SELECT d.day
         , COUNT(DISTINCT u.user_id) AS wau
         , COUNT(DISTINCT IF(u.day=d.day,u.user_id,NULL)) AS dau
      FROM ( SELECT DATE(k.ts) AS `day`
               FROM `log` k
              GROUP BY `day`
           ) d
      JOIN ( SELECT DATE(l.ts) AS `day`
                  , l.user_id
               FROM `log` l
              GROUP BY `day`, l.user_id
           ) u
        ON u.day <= d.day
       AND u.day > DATE_ADD(d.day, INTERVAL -7 DAY)
     GROUP BY d.day
     ORDER BY d.day
    


    1. 2つの日付範囲の間の等しい日数SQL

    2. SailsJS-レコードの作成時にエラーが発生せずに文字列属性の長さを指定するにはどうすればよいですか?

    3. sp_updatestatsが実際に更新するものを理解する

    4. zendフレームワークで正確なSQLクエリを出力する方法は?