PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

PostgreSQL - Obtendo dados estatísticos


Você deve pesquisar funções agregadas (min, max, count, avg), que andam de mãos dadas com GROUP BY . Para agregações baseadas em data, date_trunc também é útil.

Por exemplo, isso retornará o número de linhas por dia:
SELECT date_trunc('day', date_time) AS day_start,
       COUNT(id) AS user_count FROM tb_user
    GROUP BY date_trunc('day', date_time);

Você pode fazer a média diária usando algo assim (com um 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;

Use 'week' em vez de dia para as contagens semanais, e assim por diante (veja date_trunc documentação).

EDITAR: (A seguir, comentário:média até e inclusive 01/05/2012, ou seja, antes do dia 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;

O que está acima é muito complicado, neste caso. Isso deve dar o mesmo 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');

EDIÇÃO 2: Após sua edição, acho que o que você procura é apenas uma única média global para todo o período de existência do seu banco de dados, em vez de grupos por mês/semana/dia.

Isso deve fornecer o número médio de linhas por dia:
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

(Eu substituiria last_date_time com NOW() para fazer a média ao longo do tempo até agora, em vez de até a última visita, se não houver visita recente.)

Então, para diário, semanal e "mensal":
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

Dito isto, as conclusões que você tira dessas estatísticas podem não ser ótimas, especialmente se você quiser ver como isso muda.

Eu também normalizaria os dados por dia em vez de assumir 30 dias em um mês (se não por hora, porque nem todos os dias têm 24 horas ). Digamos que você tenha 10 visitas por dia em janeiro de 2011 e 10 visitas por dia em fevereiro de 2011. Isso lhe dá 310 visitas em janeiro e 280 visitas em fevereiro. Se você não prestar atenção, pode pensar que teve quase um Queda de 10% em número de visitantes, então algo deu errado em fevereiro, quando na verdade não é o caso.