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

Seskupit podle datových intervalů

WITH t AS (
   SELECT ts, (random()*100)::int AS bandwidth
   FROM   generate_series('2012-09-01', '2012-09-04', '1 minute'::interval) ts
   )

SELECT date_trunc('hour', ts) AS hour_stump
      ,(extract(minute FROM ts)::int / 15) AS min15_slot
      ,count(*) AS rows_in_timeslice               -- optional
      ,sum(bandwidth) AS sum_bandwidth
FROM   t
WHERE  ts >= '2012-09-02 00:00:00+02'::timestamptz -- user's time range
AND    ts <  '2012-09-03 00:00:00+02'::timestamptz -- careful with borders 
GROUP  BY 1, 2
ORDER  BY 1, 2;

CTE t poskytuje data, jako by mohla obsahovat vaše tabulka:jedno časové razítko ts za minutu s bandwidth číslo. (Tu část nepotřebujete, místo toho pracujete se svým stolem.)

Zde je velmi podobné řešení pro velmi podobnou otázku - s podrobným vysvětlením, jak tato konkrétní agregace funguje:

  • date_trunc 5minutový interval v PostgreSQL

Zde je podobné řešení pro podobnou otázku týkající se běhu součty – s podrobným vysvětlením a odkazy na různé použité funkce:

  • PostgreSQL:průběžný počet řádků pro dotaz „po minutách“

Dodatečná otázka v komentáři

WITH -- same as above ...

SELECT DISTINCT ON (1,2)
       date_trunc('hour', ts) AS hour_stump
      ,(extract(minute FROM ts)::int / 15) AS min15_slot
      ,bandwidth AS bandwith_sample_at_min15
FROM   t
WHERE  ts >= '2012-09-02 00:00:00+02'::timestamptz
AND    ts <  '2012-09-03 00:00:00+02'::timestamptz
ORDER  BY 1, 2, ts DESC;

Načte jeden neagregovaný vzorek za 15minutový interval – z posledního dostupného řádku v okně. Pokud řada nebude chybět, bude to 15. minuta. Rozhodující části jsou DISTINCT ON a ORDER BY .
Více informací o použité technice zde:

  • Vybrat první řádek v každé skupině GROUP BY?


  1. Jak vytvořit VARRAY jako databázový objekt v databázi Oracle

  2. Rozdíl mezi sys.columns, sys.system_columns a sys.all_columns na serveru SQL Server

  3. Jednoduchý způsob, jak transponovat sloupce a řádky v SQL?

  4. Která syntaxe spojení je lepší?