sql >> Databáze >  >> RDS >> PostgreSQL

PostgreSQL - Získávání statistických dat

Měli byste se podívat na agregační funkce (min, max, count, avg), které jdou ruku v ruce s GROUP BY . Pro agregace na základě data date_trunc je také užitečné.

Například to vrátí počet řádků za den:

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

Denní průměr pak můžete udělat pomocí něčeho takového (s 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;

Použijte 'week' místo dne pro týdenní počty a tak dále (viz date_trunc dokumentace).

UPRAVIT: (Následující komentář:průměr do 1. 5. 2012 včetně, tj. před 6. dnem.)

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 je uvedeno výše, je v tomto případě příliš komplikované. To by vám mělo dát stejný výsledek:

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

ÚPRAVA 2: Po vaší úpravě předpokládám, že to, co hledáte, je pouze jeden globální průměr za celou dobu existence vaší databáze, spíše než skupiny podle měsíce/týdne/dne.

To by vám mělo poskytnout průměrný počet řádků za den:

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

(Nahradil bych last_date_time pomocí NOW() abyste vytvořili průměr za dobu až do současnosti, spíše než do poslední návštěvy, pokud nedošlo k žádné nedávné návštěvě.)

Poté pro denní, týdenní a „měsíční“:

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

Jak již bylo řečeno, závěry, které z takových statistik vyvodíte, nemusí být skvělé, zvláště pokud chcete vidět, jak se to změní.

Také bych raději normalizoval data za den, než abych předpokládal 30 dní v měsíci (pokud ne za hodinu, protože ne všechny dny mají 24 hodin ). Řekněme, že máte 10 návštěv denně v lednu 2011 a 10 návštěv denně v únoru 2011. To vám dává 310 návštěv v lednu a 280 návštěv v únoru. Pokud nebudete dávat pozor, můžete si myslet, že jste měli téměř 10% pokles, pokud jde o počet návštěvníků, takže se něco pokazilo v únoru, kdy tomu tak opravdu nebylo.




  1. sql vygeneruje jedinečný název tabulky/zobrazení

  2. Seřadit sloupce pro dynamické pivotování

  3. Jak používat klauzuli GROUP BY v SQL

  4. Jak vytvořit dotaz v Drupal 8