PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Cách nhận giá trị trung bình cho các khoảng thời gian trong Postgres

Thiết kế DB

Trong khi bạn có thể làm việc với date riêng biệt và time thực sự không có lợi thế so với một timestamp cột. Tôi sẽ điều chỉnh:

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;

Nếu ngày và giờ không phải là date thực tế và time kiểu dữ liệu, sử dụng to_timestamp() . Có liên quan:

Truy vấn

Sau đó, truy vấn đơn giản hơn một chút:

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 tại đây

Tạo lưới thời gian bắt đầu trong grid truy vấn con đầu tiên , chạy từ vòng loại đầu tiên đến cuối cùng hàng trong khung thời gian nhất định.

Tham gia vào các hàng nằm trong mỗi phân vùng bằng LATERAL tham gia và tổng hợp ngay các giá trị trung bình trong truy vấn con avg . Do các uẩn, nó luôn luôn trả về một hàng ngay cả khi không tìm thấy mục nhập nào. Giá trị trung bình mặc định là NULL trong trường hợp này.

Kết quả bao gồm tất cả các khoảng thời gian giữa hàng đủ điều kiện đầu tiên và cuối cùng trong khung thời gian nhất định. Nhiều thành phần kết quả khác cũng sẽ có ý nghĩa. Như bao gồm tất cả các khe thời gian trong khung thời gian nhất định hoặc chỉ các khe thời gian có giá trị thực tế. Tất cả có thể, tôi phải chọn một cách diễn giải.

Chỉ mục

Ít nhất phải có chỉ mục đa cột này:

CRATE INDEX foo_idx ON tbl (sn, ts);

Hoặc trên (sn, ts, vin1, vin2, vin3) để cho phép quét chỉ theo chỉ mục - nếu một số điều kiện tiên quyết được đáp ứng và đặc biệt nếu các hàng trong bảng rộng hơn nhiều so với trong bản trình diễn.

Liên quan chặt chẽ:

Dựa trên bảng gốc của bạn

Theo yêu cầu và làm rõ trong nhận xét và sau đó được cập nhật lại trong câu hỏi để bao gồm các cột macloc . Tôi giả sử bạn muốn các giá trị trung bình riêng biệt cho mỗi (mac, loc) .

datetime vẫn là các cột riêng biệt, các cột vin * là loại float và loại trừ các khoảng thời gian không có hàng:

Truy vấn cập nhật cũng di chuyển hàm set-return generate_series() đến FROM danh sách này rõ ràng hơn trước 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;

Tạo chỉ mục biểu thức đa cột để hỗ trợ điều này:

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

db <> fiddle tại đây

Nhưng tôi muốn sử dụng timestamp tất cả cùng.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tại sao truy vấn không được lưu trong tệp csv trong khi nó có vẻ bình thường trong bảng điều khiển postgresql

  2. Làm cách nào để tạo sự di chuyển đường ray để loại bỏ / thay đổi độ chính xác và tỷ lệ trên số thập phân?

  3. Làm cách nào để khởi động PostgreSQL trên Windows?

  4. Khóa nào, nếu có, có sử dụng 'CREATE TRIGGER' trong PostgreSQL 9.4.2 không

  5. xác thực mật khẩu không thành công cho người dùng cây đậu đàn hồi ebroot