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

Tổng chênh lệch thời gian giữa các hàng

Khó khăn đặc biệt là không bỏ lỡ các khoảng thời gian đến khung thời gian bên ngoài.
Giả sử rằng hàng tiếp theo cho bất kỳ id nào đã cho luôn có trạng thái ngược lại.
Sử dụng tên cột ts thay vì recordTime :

WITH span AS (
   SELECT '2014-03-01 13:00'::timestamp AS s_from  -- start of time range
        , '2014-03-01 14:00'::timestamp AS s_to    -- end of time range
   )
, cte AS (
   SELECT id, ts, status, s_to
        , lead(ts, 1, s_from) OVER w AS span_start
        , first_value(ts)     OVER w AS last_ts
   FROM   span s
   JOIN   tbl  t ON t.ts BETWEEN s.s_from AND s.s_to
   WINDOW w AS (PARTITION BY id ORDER BY ts DESC)
   )
SELECT id, sum(time_disconnected)::text AS total_disconnected
FROM  (
   SELECT id, ts - span_start AS time_disconnected
   FROM   cte
   WHERE  status = 'Connected'

   UNION  ALL  
   SELECT id, s_to - ts
   FROM   cte
   WHERE  status = 'Disconnected'
   AND    ts = last_ts
   ) sub
GROUP  BY 1
ORDER  BY 1;

Trả về các khoảng thời gian được yêu cầu. Các ID
không có mục nhập trong phạm vi thời gian đã chọn sẽ không hiển thị. Bạn sẽ phải truy vấn thêm chúng.

SQL Fiddle.
Lưu ý:Tôi truyền total_disconnected kết quả thành text trong fiddle, bởi vì loại interval được hiển thị ở định dạng khủng khiếp.

Thêm ID mà không cần nhập trong khung thời gian đã chọn


Thêm vào truy vấn ở trên (trước ORDER BY 1 cuối cùng ):

...
UNION  ALL
SELECT id, total_disconnected
   FROM  (
   SELECT DISTINCT ON (id)
          t.id, t.status, (s.s_to - s.s_from)::text AS total_disconnected
   FROM   span     s
   JOIN   tbl      t ON t.ts < s.s_from  -- only from before time range
   LEFT   JOIN cte c USING (id)
   WHERE  c.id IS NULL         -- not represented in selected time frame
   ORDER  BY t.id, t.ts DESC   -- only the latest entry
   ) sub
WHERE  status = 'Disconnected' -- only if disconnected
ORDER  BY 1;

SQL Fiddle.

Giờ đây, chỉ những ID không có mục nhập hoặc trước đó phạm vi thời gian đã chọn không hiển thị.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách chạy Jasmine trước Tất cả cho tất cả các tệp thử nghiệm

  2. Cách ẩn trang trí tập hợp kết quả trong đầu ra Psql

  3. Làm cách nào để chuyển cơ sở dữ liệu sản xuất sang dàn dựng trên Heroku bằng cách sử dụng pgbackups? Bắt lỗi

  4. Tạo mã loại bắt buộc JOOQ

  5. Cách sử dụng chỉ mục trong truy vấn SELECT MAX (id) bảng ngoại trong PostgreSQL?