Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Tygodniowo Aktywni Użytkownicy na każdy dzień z logu

Aby uzyskać „średnią liczbę użytkowników tygodniowo” (zgodnie z moim rozumieniem Twojej specyfikacji... „dla każdego dnia, liczba różnych identyfikatorów użytkownika widocznych w ciągu tego dnia i poprzednich sześciu dni”), zapytanie zgodne z poniższym może być używany. (Zapytanie zwraca również „dzienną średnią liczbę użytkowników”.

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

(Jeszcze nie przeprowadziłem testu tego; ale zrobię to później i zaktualizuję to oświadczenie, jeśli będą potrzebne jakiekolwiek poprawki.)

To zapytanie dołącza do listy użytkowników na dany dzień (z u rowsource) do zestawu dni z tabeli dziennika (d źródło wierszy). Zwróć uwagę na literał „7”, który pojawia się w predykacie złączenia (klauzula ON), to właśnie on powoduje „dopasowanie” listy użytkowników do ostatnich 6 dni.

Zwróć uwagę, że można to również rozszerzyć, aby uzyskać liczbę odrębnych użytkowników w ciągu ostatnich 3 dni, na przykład przez dodanie innego wyrażenia na liście SELECT.

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

Dosłowne „7” można zwiększyć, aby uzyskać większy zasięg. I ten literał 3 w powyższym wyrażeniu można zmienić, aby uzyskać dowolną liczbę dni... musimy tylko upewnić się, że mamy wystarczająco dużo wierszy z poprzedniego dnia (z d ) dołączony do każdego wiersza z u .

INFORMACJA O WYDAJNOŚCI:Ze względu na widoki wbudowane (lub tabele pochodne, jak je nazywa MySQL), to zapytanie może nie być zbyt szybkie, ponieważ zestawy wyników dla tych widoków wbudowanych muszą zostać zmaterializowane w pośrednich tabelach MyISAM.

Widok wbudowany aliasem u może nie być optymalna; może być szybciej dołączyć bezpośrednio do tabeli dziennika. Myślałem w kategoriach uzyskania unikalnej listy użytkowników na dany dzień, co dało mi to zapytanie w widoku wbudowanym. Po prostu łatwiej było mi pojąć, co się dzieje. Myślałem, że jeśli masz setki tych samych użytkowników wprowadzonych w ciągu dnia, widok wbudowany wyeliminowałby całą masę duplikatów, zanim zrobimy połączenie z innymi dniami. Klauzula WHERE ograniczająca liczbę dni, w których powracających najlepiej dodać w u i d widoki wbudowane. (d widok wbudowany musiałby obejmować dodatkowe wcześniejsze 6 dni).

Z drugiej strony, jeśli kolumna ts jest typem danych TIMESTAMP, byłbym bardziej skłonny użyć DATE(ts) wyrażenie do wyodrębnienia części daty. Ale to zwróci typ danych DATE w zestawie wyników zamiast liczby całkowitej, która byłaby inna niż określony zestaw wyników).

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. Czy pozostawianie połączenia mysql otwartego przez stronę jest całkowicie lekkomyślne?

  2. jak zapisać dane, które użytkownik wprowadził na stronie formularza po wykonaniu skryptu?

  3. Jak korzystać z implementacji AES_DECRYPT() MySQL przez Python?

  4. Przygotowana instrukcja PDO fetch() zwracająca podwójne wyniki

  5. PHP - Wstaw datę do mysql