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

SQL - Tìm tất cả thời gian ngừng hoạt động và độ dài của thời gian ngừng hoạt động từ dữ liệu MySQL (tập hợp các hàng có tem thời gian và thông báo trạng thái)

Đây là một cách tiếp cận.

Bắt đầu bằng cách sắp xếp các hàng trạng thái theo dấu thời gian (chế độ xem nội tuyến được đặt bí danh là s ). Sau đó, sử dụng các biến người dùng MySQL để giữ các giá trị từ các hàng trước khi bạn xử lý qua từng hàng.

Những gì chúng tôi thực sự đang tìm kiếm là trạng thái 'tăng' ngay sau một chuỗi trạng thái 'xuống'. Và khi chúng tôi tìm thấy hàng có trạng thái 'tăng', điều chúng tôi thực sự cần là dấu thời gian sớm nhất từ ​​chuỗi trạng thái 'giảm' trước đó.

Vì vậy, một cái gì đó như thế này sẽ hoạt động:

SELECT d.start_down
     , d.ended_down
  FROM (SELECT @i := @i + 1 AS i
             , @start := IF(s.status = 'down' AND (@status = 'up' OR @i = 1), s.time, @start) AS start_down
             , @ended := IF(s.status = 'up' AND @status = 'down', s.time, NULL) AS ended_down
             , @status := s.status
         FROM (SELECT t.time
                    , t.status
                 FROM mydata t
                WHERE t.status IN ('up','down')
                ORDER BY t.time ASC, t.status ASC
              ) s
         JOIN (SELECT @i := 0, @status := 'up', @ended := NULL, @start := NULL) i
      ) d
WHERE d.start_down IS NOT NULL
  AND d.ended_down IS NOT NULL

Điều này phù hợp với tập dữ liệu cụ thể mà bạn hiển thị.

Điều này không xử lý được (những gì nó không trả về) là một khoảng thời gian 'xuống' chưa kết thúc, tức là một chuỗi trạng thái 'xuống' mà không có trạng thái 'lên' theo sau.

Để tránh thao tác sắp xếp tệp để trả về các hàng theo thứ tự, bạn sẽ muốn có một chỉ mục bao gồm trên (time,status) . Truy vấn này sẽ tạo một bảng (MyISAM) tạm thời để hiện thực hóa chế độ xem nội tuyến có bí danh là d .

LƯU Ý: Để hiểu truy vấn này đang làm gì, hãy bóc truy vấn ngoài cùng và chỉ chạy truy vấn cho chế độ xem nội tuyến có bí danh là d (bạn có thể thêm s.time vào danh sách đã chọn.)

Truy vấn này nhận được mọi hàng có trạng thái "lên" hoặc "xuống". "Thủ thuật" là nó chỉ định cả thời gian "bắt đầu" và "kết thúc" (đánh dấu khoảng thời gian giảm) chỉ trên các hàng kết thúc khoảng thời gian 'giảm'. (Tức là hàng đầu tiên có trạng thái 'tăng' sau các hàng có trạng thái 'xuống'.) Đây là nơi công việc thực sự được thực hiện, truy vấn ngoài cùng chỉ lọc ra tất cả các hàng "bổ sung" trong tập kết quả này (mà chúng tôi không cần.)

SELECT @i := @i + 1 AS i
     , @start := IF(s.status = 'down' AND (@status = 'up' OR @i = 1), s.time, @start) AS start_down
     , @ended := IF(s.status = 'up' AND @status = 'down', s.time, NULL) AS ended_down
     , @status := s.status
     , s.time
  FROM (SELECT t.time
             , t.status
          FROM mydata t
         WHERE t.status IN ('up','down')
         ORDER BY t.time ASC, t.status ASC
       ) s
  JOIN (SELECT @i := 0, @status := 'up', @ended := NULL, @start := NULL) i

Mục đích của chế độ xem nội tuyến được đặt bí danh là s là lấy các hàng được sắp xếp theo giá trị dấu thời gian, vì vậy chúng tôi có thể xử lý chúng theo trình tự. Chế độ xem nội tuyến có bí danh là i chỉ ở đó để chúng tôi có thể khởi tạo một số biến người dùng khi bắt đầu truy vấn.

Nếu chúng tôi đang chạy trên Oracle hoặc SQL Server, chúng tôi có thể sử dụng "các hàm phân tích" hoặc "các hàm xếp hạng" (như chúng được đặt tên tương ứng.) MySQL không cung cấp bất kỳ thứ gì như vậy, vì vậy chúng tôi phải "tự mình thực hiện ".



  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ần một truy vấn mysql

  2. REGEXP Với PDO Mysql

  3. PDO + MySQL luôn trả về chuỗi, nhưng MsSQL thì sao?

  4. Sự cố LAG / LEAD của MySQL

  5. Cách đơn giản để đọc một bản ghi từ MySQL