sql >> Base de Datos >  >> RDS >> PostgreSQL

PostgreSQL - Obtener datos estadísticos

Debe buscar en funciones agregadas (min, max, count, avg), que van de la mano con GROUP BY . Para agregaciones basadas en fechas, date_trunc también es útil.

Por ejemplo, esto devolverá el número de filas por día:

SELECT date_trunc('day', date_time) AS day_start,
       COUNT(id) AS user_count FROM tb_user
    GROUP BY date_trunc('day', date_time);

Luego puede hacer el promedio diario usando algo como esto (con a 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;

Usa 'week' en lugar de día para los conteos semanales, y así sucesivamente (ver date_trunc documentación).

EDITAR: (Comentario siguiente:promedio hasta el 1/5/2012 inclusive, es decir, antes del 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;

Lo que está arriba es demasiado complicado, en este caso. Esto debería darte el mismo resultado:

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');

EDICIÓN 2: Después de su edición, supongo que lo que busca es solo un promedio global único para todo el período de existencia de su base de datos, en lugar de grupos por mes/semana/día.

Esto debería darte el número promedio de filas por día:

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

(Reemplazaría last_date_time con NOW() para hacer el promedio durante el tiempo hasta ahora, en lugar de hasta la última visita, si no hay una visita reciente).

Luego, para diario, semanal y "mensual":

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

Dicho esto, las conclusiones que extraigas de tales estadísticas pueden no ser muy buenas, especialmente si quieres ver cómo cambia.

También normalizaría los datos por día en lugar de asumir 30 días en un mes (si no por hora, porque no todos los días tienen 24 horas ). Digamos que tiene 10 visitas por día en enero de 2011 y 10 visitas por día en febrero de 2011. Eso le da 310 visitas en enero y 280 visitas en febrero. Si no presta atención, podría pensar que ha tenido casi un Caída del 10 % en términos de número de visitantes, por lo que algo salió mal en febrero, cuando en realidad no es así.