PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

PostgreSQL - Abrufen statistischer Daten

Sie sollten sich Aggregatfunktionen ansehen (min, max, count, avg), die Hand in Hand gehen mit GROUP BY . Für datumsbasierte Aggregationen date_trunc ist auch nützlich.

Dies gibt beispielsweise die Anzahl der Zeilen pro Tag zurück:

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

Sie können dann den täglichen Durchschnitt mit so etwas berechnen (mit einem 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;

Verwenden Sie 'week' statt Tag für die wöchentlichen Zählungen usw. (siehe date_trunc Dokumentation).

BEARBEITEN: (Folgender Kommentar:Durchschnitt bis einschließlich 1.5.2012, also vor dem 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;

Was oben ist, ist in diesem Fall zu kompliziert. Dies sollte das gleiche Ergebnis liefern:

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

BEARBEITEN 2: Nach Ihrer Bearbeitung schätze ich, was Sie suchen, ist nur ein einziger globaler Durchschnitt für den gesamten Zeitraum des Bestehens Ihrer Datenbank, anstatt Gruppen nach Monat/Woche/Tag.

Dies sollte Ihnen die durchschnittliche Anzahl von Zeilen pro Tag geben:

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

(Ich würde last_date_time ersetzen mit NOW() um den Durchschnitt über die Zeit bis jetzt zu machen, anstatt bis zum letzten Besuch, wenn es keinen kürzlichen Besuch gibt.)

Dann für täglich, wöchentlich und "monatlich":

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

Davon abgesehen sind die Schlussfolgerungen, die Sie aus solchen Statistiken ziehen, möglicherweise nicht besonders gut, insbesondere wenn Sie sehen möchten, wie sich diese ändern.

Ich würde auch die Daten pro Tag normalisieren, anstatt 30 Tage in einem Monat anzunehmen (wenn nicht pro Stunde, weil nicht alle Tage 24 Stunden haben). ). Angenommen, Sie haben 10 Besuche pro Tag im Januar 2011 und 10 Besuche pro Tag im Februar 2011. Das ergibt 310 Besuche im Januar und 280 Besuche im Februar. Wenn Sie nicht aufpassen, könnten Sie denken, Sie hätten fast einen 10 % weniger Besucher, also ist im Februar etwas schief gelaufen, obwohl das nicht der Fall ist.