PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Cara mendapatkan nilai rata-rata untuk interval waktu di Postgres

Desain DB

Sementara Anda bisa bekerja dengan date yang terpisah dan time kolom, benar-benar tidak ada keuntungan dari satu timestamp kolom. Saya akan beradaptasi:

ALTER TABLE tbl ADD column ts timestamp;
UPDATE tbl SET ts = date + time;  -- assuming actual date and time types
ALTER TABLE tbl DROP column date, DROP column time;

Jika tanggal dan waktu bukan date yang sebenarnya dan time tipe data, gunakan to_timestamp() . Terkait:

Kueri

Maka kuerinya sedikit lebih sederhana:

SELECT *
FROM  (
   SELECT sn, generate_series(min(ts), max(ts), interval '5 min') AS ts
   FROM   tbl
   WHERE  sn = '4as11111111'
   AND    ts >= '2018-01-01'
   AND    ts <  '2018-01-02'
   GROUP  BY 1
   ) grid
CROSS  JOIN LATERAL (
   SELECT round(avg(vin1), 2) AS vin1_av
        , round(avg(vin2), 2) AS vin2_av
        , round(avg(vin3), 2) AS vin3_av
   FROM   tbl
   WHERE  sn =  grid.sn
   AND    ts >= grid.ts
   AND    ts <  grid.ts + interval '5 min'
   ) avg;

db<>fiddle di sini

Hasilkan kisi waktu mulai di subkueri pertama grid , berjalan dari kualifikasi pertama hingga terakhir baris dalam jangka waktu tertentu.

Gabung ke baris yang ada di setiap partisi dengan LATERAL bergabung dan segera agregat rata-rata di subkueri avg . Karena agregat, selalu mengembalikan baris bahkan jika tidak ada entri yang ditemukan. Rata-rata default ke NULL dalam hal ini.

Hasilnya mencakup semua slot waktu antara baris kualifikasi pertama dan terakhir dalam jangka waktu tertentu. Berbagai komposisi hasil lainnya juga masuk akal. Suka sertakan semua slot waktu dalam kerangka waktu tertentu atau hanya slot waktu dengan nilai aktual. Sebisa mungkin, saya harus memilih satu interpretasi.

Indeks

Setidaknya memiliki indeks multikolom ini:

CRATE INDEX foo_idx ON tbl (sn, ts);

Atau di (sn, ts, vin1, vin2, vin3) untuk mengizinkan pemindaian indeks saja - jika beberapa prasyarat terpenuhi dan terutama jika baris tabel jauh lebih lebar daripada di demo.

Berhubungan erat:

Berdasarkan tabel asli Anda

Seperti yang diminta dan diklarifikasi di komentar , dan kemudian diperbarui lagi dalam pertanyaan untuk memasukkan kolom mac dan loc . Saya berasumsi Anda ingin rata-rata terpisah per (mac, loc) .

date dan time masih kolom terpisah, kolom vin* adalah tipe float , dan mengecualikan slot waktu tanpa baris:

Kueri yang diperbarui juga memindahkan fungsi pengembalian set generate_series() ke FROM list, yang lebih bersih sebelum Postgres 10:

SELECT t.mac, sn.sn, t.loc, ts.ts::time AS time, ts.ts::date AS date
     , t.vin1_av, t.vin2_av, t.vin3_av
FROM  (SELECT text '4as11111111') sn(sn)  -- provide sn here once
CROSS  JOIN LATERAL (
   SELECT min(date+time) AS min_ts, max(date+time) AS max_ts
   FROM   tbl
   WHERE  sn = sn.sn
   AND    date+time >= '2018-01-01 0:0'   -- provide time frame here
   AND    date+time <  '2018-01-02 0:0'
   ) grid
CROSS  JOIN LATERAL generate_series(min_ts, max_ts, interval '5 min') ts(ts)
CROSS  JOIN LATERAL (
   SELECT mac, loc
        , round(avg(vin1)::numeric, 2) AS vin1_av  -- cast to numeric for round()
        , round(avg(vin2)::numeric, 2) AS vin2_av  -- but rounding is optional
        , round(avg(vin3)::numeric, 2) AS vin3_av
   FROM   tbl
   WHERE  sn = sn.sn
   AND    date+time >= ts.ts
   AND    date+time <  ts.ts + interval '5 min'
   GROUP  BY mac, loc
   HAVING count(*) > 0  -- exclude empty slots
   ) t;

Buat indeks ekspresi multikolom untuk mendukung ini:

CRATE INDEX bar_idx ON tbl (sn, (date+time));

db<>fiddle di sini

Tapi saya lebih suka menggunakan timestamp selama ini.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Alternatif pghoard - Manajemen Pencadangan PostgreSQL dengan ClusterControl

  2. Cara membuat daftar kunci asing tabel

  3. Bagaimana menginterpretasikan nilai PosgreSQL txid_current()

  4. Erlang dan PostgreSQL

  5. Django mengatur ulang bidang pk/id peningkatan otomatis untuk produksi