Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Pengguna Aktif Mingguan untuk setiap hari dari log

Untuk mendapatkan jumlah "Pengguna Rata-Rata Mingguan" (sesuai pemahaman saya tentang spesifikasi Anda... "untuk setiap hari, jumlah user_id berbeda yang terlihat selama hari itu dan enam hari sebelumnya"), kueri di sepanjang baris di bawah ini bisa digunakan. (Kueri juga mengembalikan jumlah "Pengguna Rata-Rata Harian".

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

(Saya belum menjalankan pengujian ini; tetapi saya akan melakukannya nanti, dan saya akan memperbarui pernyataan ini jika ada koreksi yang diperlukan.)

Kueri ini bergabung dengan daftar pengguna untuk hari tertentu (dari u rowsource), ke satu set hari dari tabel log (d sumber baris). Perhatikan literal "7" yang muncul di predikat gabungan (klausa AKTIF), itulah yang membuat daftar pengguna "cocok" dengan 6 hari sebelumnya.

Perhatikan bahwa ini juga dapat diperpanjang untuk mendapatkan jumlah pengguna yang berbeda selama 3 hari terakhir, misalnya, dengan menambahkan ekspresi lain dalam daftar SELECT.

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

"7" literal itu dapat ditingkatkan untuk mendapatkan rentang yang lebih besar. Dan 3 literal dalam ekspresi di atas dapat diubah untuk mendapatkan berapa pun jumlah hari... kita hanya perlu memastikan bahwa kita memiliki cukup baris hari sebelumnya (dari d ) bergabung ke setiap baris dari u .

CATATAN KINERJA:Karena tampilan sebaris (atau tabel turunan, seperti yang disebut MySQL), kueri ini mungkin tidak terlalu cepat, karena kumpulan hasil untuk tampilan sebaris tersebut harus diwujudkan ke dalam tabel MyISAM perantara.

Tampilan sebaris alias sebagai u mungkin tidak optimal; mungkin lebih cepat untuk bergabung langsung ke tabel log. Saya berpikir untuk mendapatkan daftar pengguna yang unik untuk hari tertentu, itulah yang saya dapatkan dari kueri dalam tampilan sebaris. Itu hanya lebih mudah bagi saya untuk mengkonseptualisasikan apa yang sedang terjadi. Dan saya berpikir bahwa jika Anda memiliki ratusan pengguna yang sama masuk untuk hari itu, tampilan sebaris akan menyingkirkan sejumlah besar duplikat, sebelum kita bergabung ke hari-hari lainnya. Klausa WHERE untuk membatasi jumlah hari kita yang kembali sebaiknya ditambahkan di dalam u dan d tampilan sebaris. (d tampilan sebaris perlu menyertakan tambahan 6 hari sebelumnya.)

Pada catatan lain, jika kolom ts adalah tipe data TIMESTAMP, saya akan lebih cenderung menggunakan DATE(ts) ekspresi untuk mengekstrak bagian tanggal. Tapi itu akan mengembalikan tipe data DATE di kumpulan hasil, bukan bilangan bulat, yang akan berbeda dari kumpulan hasil yang Anda tentukan.)

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apa yang akan terjadi jika 2 orang atau lebih mencoba memperbarui tabel MySQL yang sama secara bersamaan?

  2. Bagaimana cara menyimpan Hasil Kueri dalam variabel menggunakan mysql

  3. persimpangan banyak-ke-banyak dan banyak-ke-banyak

  4. Apa susunan MySQL terbaik untuk bahasa Jerman?

  5. Di mana saya dapat mengunduh sampel database Mysql?