Powinieneś zajrzeć do funkcji agregujących
(min, max, count, avg), które idą w parze z GROUP BY
. W przypadku agregacji opartych na datach date_trunc
jest również przydatne.
Na przykład zwróci to liczbę wierszy dziennie:
SELECT date_trunc('day', date_time) AS day_start,
COUNT(id) AS user_count FROM tb_user
GROUP BY date_trunc('day', date_time);
Następnie możesz wykonać średnią dzienną, używając czegoś takiego (z CTE ):
WITH daily_count AS (SELECT date_trunc('day', date_time) AS day_start,
COUNT(id) AS user_count FROM tb_user
GROUP BY date_trunc('day', date_time))
SELECT AVG(user_count) FROM daily_count;
Użyj 'week'
zamiast dnia dla liczników tygodniowych i tak dalej (zobacz date_trunc
dokumentacja).
EDYTUJ: (Poniższy komentarz:średnia do 1.05.2012 włącznie, tj. przed 6.)
WITH daily_count AS (SELECT date_trunc('day', date_time) AS day_start,
COUNT(id) AS user_count
FROM tb_user
WHERE date_time >= DATE('2012-01-01') AND date_time < DATE('2012-01-06')
GROUP BY date_trunc('day', date_time))
SELECT SUM(user_count)/(DATE('2012-01-06') - DATE('2012-01-01')) FROM daily_count;
To, co powyżej, jest w tym przypadku zbyt skomplikowane. To powinno dać ten sam wynik:
SELECT COUNT(id)/(DATE('2012-01-06') - DATE('2012-01-01'))
FROM tb_user
WHERE date_time >= DATE('2012-01-01') AND date_time < DATE('2012-01-06');
EDYCJA 2: Po Twojej edycji, myślę, że to, czego szukasz, to tylko jedna globalna średnia z całego okresu istnienia Twojej bazy danych, a nie grupowanie według miesiąca/tygodnia/dzień.
Powinno to dać średnią liczbę wierszy dziennie:
WITH total_min_max AS (SELECT
COUNT(id) AS total_visits,
MIN(date_time) AS first_date_time,
MAX(date_time) AS last_date_time,
FROM tb_user)
SELECT total_visits/((last_date_time::date-first_date_time::date)+1) AS users_per_day
FROM total_min_max
(Zamieniłbym last_date_time
z NOW()
aby uzyskać średnią do chwili obecnej, a nie do ostatniej wizyty, jeśli nie ma ostatnich odwiedzin).
Następnie dla dziennych, tygodniowych i „miesięcznych”:
WITH daily_avg AS (
WITH total_min_max AS (SELECT
COUNT(id) AS total_visits,
MIN(date_time) AS first_date_time,
MAX(date_time) AS last_date_time,
FROM tb_user)
SELECT total_visits/((last_date_time::date-first_date_time::date)+1) AS users_per_day
FROM total_min_max)
SELECT
users_per_day,
(users_per_day * 7) AS users_per_week,
(users_per_month * 30) AS users_per_month
FROM daily_avg
Biorąc to pod uwagę, wnioski, które wyciągasz z takich statystyk, mogą nie być wspaniałe, zwłaszcza jeśli chcesz zobaczyć, jak to się zmienia.
Normalizowałbym również dane na dzień, zamiast zakładać 30 dni w miesiącu (jeśli nie na godzinę, ponieważ nie wszystkie dni mają 24 godziny ). Załóżmy, że masz 10 wizyt dziennie w styczniu 2011 i 10 wizyt dziennie w lutym 2011. To daje 310 wizyt w styczniu i 280 wizyt w lutym. 10% spadek pod względem liczby odwiedzających, więc coś poszło nie tak w lutym, kiedy w rzeczywistości tak nie jest.