sql >> Database teknologi >  >> RDS >> PostgreSQL

PostgreSQL - Hentning af statistiske data

Du bør se nærmere på samlede funktioner (min, max, count, avg), som går hånd i hånd med GROUP BY . For datobaserede sammenlægninger, date_trunc er også nyttig.

For eksempel vil dette returnere antallet af rækker pr. dag:

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

Du kan derefter lave det daglige gennemsnit ved at bruge noget som dette (med en 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;

Brug 'week' i stedet for dag for de ugentlige optællinger og så videre (se date_trunc dokumentation).

EDIT: (Følgende kommentar:gennemsnit til og med 5/1/2012, dvs. før den 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;

Ovenstående er alt for kompliceret i dette tilfælde. Dette skulle give dig det samme resultat:

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

EDIT 2: Efter din redigering gætter jeg på, at det, du leder efter, kun er et enkelt globalt gennemsnit for hele din databases eksistensperiode, snarere end grupperinger efter måned/uge/dag.

Dette skulle give dig det gennemsnitlige antal rækker pr. dag:

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

(Jeg ville erstatte last_date_time med NOW() at lave gennemsnittet over tiden indtil nu, i stedet for indtil det sidste besøg, hvis der ikke er noget nyligt besøg.)

Derefter for daglig, ugentlig og "månedlig":

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

Når det er sagt, er konklusioner, du drager fra sådanne statistikker, måske ikke gode, især hvis du vil se, hvordan den ændrer sig.

Jeg ville også normalisere dataene pr. dag i stedet for at antage 30 dage i en måned (hvis ikke pr. time, fordi ikke alle dage har 24 timer ). Lad os sige, at du har 10 besøg om dagen i januar 2011 og 10 besøg om dagen i februar 2011. Det giver dig 310 besøg i januar og 280 besøg i februar. Hvis du ikke er opmærksom, kunne du tro, at du har haft en næsten en 10 % fald i antallet af besøgende, så noget gik galt i februar, hvor det virkelig ikke er tilfældet.




  1. Installer webserver i Windows XP med Apache2, PHP5 og MySQL4 – del 1

  2. Design af relationer omkring en arvestruktur

  3. MySQL på Azure Performance Benchmark – ScaleGrid vs. Azure Database

  4. Datagridview-celleværdiændringsopdateringsdatabase