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

Phương pháp tìm khoảng trống trong dữ liệu chuỗi thời gian trong MySQL?

Để bắt đầu, hãy để chúng tôi tóm tắt số lượng mục nhập theo giờ trong bảng của bạn.

SELECT CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME) hour,
       COUNT(*) samplecount
  FROM table
 GROUP BY CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME)

Bây giờ, nếu bạn ghi nhật ký thứ gì đó sáu phút một lần (mười lần một giờ) thì tất cả các giá trị số lượng mẫu của bạn phải là mười. Biểu thức này:CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME) trông có vẻ lông nhưng nó chỉ đơn giản là cắt ngắn các dấu thời gian của bạn thành giờ mà chúng xuất hiện bằng cách bỏ đi phút và giây.

Điều này là hợp lý hiệu quả và sẽ giúp bạn bắt đầu. Sẽ rất hiệu quả nếu bạn có thể đặt một chỉ mục trên cột entry_time của mình và giới hạn truy vấn của bạn, chẳng hạn như các mẫu của ngày hôm qua như được hiển thị ở đây.

SELECT CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME) hour,
       COUNT(*) samplecount
  FROM table
 WHERE entry_time >= CURRENT_DATE - INTERVAL 1 DAY
   AND entry_time < CURRENT_DATE
 GROUP BY CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME)

Nhưng việc phát hiện hàng giờ trôi qua với các mẫu bị thiếu là không tốt lắm. Nó cũng hơi nhạy cảm với rung động trong quá trình lấy mẫu của bạn. Có nghĩa là, nếu mẫu cập nhật hàng giờ của bạn đôi khi sớm nửa giây (10:59:30) và đôi khi trễ nửa giây (11:00:30), tổng số tóm tắt hàng giờ của bạn sẽ bị tắt. Vì vậy, thứ tóm tắt giờ này (hoặc tóm tắt ngày, hoặc tóm tắt phút, v.v.) không phải là chống đạn.

Bạn cần một truy vấn tự tham gia để có được nội dung hoàn toàn chính xác; nó hơi giống một quả cầu lông và gần như không hiệu quả.

Hãy bắt đầu bằng cách tạo cho mình một bảng ảo (truy vấn con) như thế này với các mẫu được đánh số. (Đây là một khó khăn trong MySQL; một số DBMS đắt tiền khác làm cho nó dễ dàng hơn. Không có vấn đề gì.)

  SELECT @sample:[email protected]+1 AS entry_num, c.entry_time, c.value
    FROM (
        SELECT entry_time, value
      FROM table
         ORDER BY entry_time
    ) C,
    (SELECT @sample:=0) s

Bảng ảo nhỏ này cung cấp entry_num, entry_time, value.

Bước tiếp theo, chúng tôi kết hợp nó với chính nó.

SELECT one.entry_num, one.entry_time, one.value, 
       TIMEDIFF(two.value, one.value) interval
  FROM (
     /* virtual table */
  ) ONE
  JOIN (
     /* same virtual table */
  ) TWO ON (TWO.entry_num - 1 = ONE.entry_num)

Điều này xếp hai bảng tiếp theo với nhau, bù đắp bởi một mục nhập duy nhất, được điều chỉnh bởi mệnh đề ON của JOIN.

Cuối cùng, chúng tôi chọn các giá trị từ bảng này với một khoảng interval lớn hơn ngưỡng của bạn và có thời gian của các mẫu ngay trước các mẫu bị thiếu.

Toàn bộ truy vấn tự tham gia là điều này. Tôi đã nói với bạn đó là một quả bóng tóc.

SELECT one.entry_num, one.entry_time, one.value, 
       TIMEDIFF(two.value, one.value) interval
  FROM (
    SELECT @sample:[email protected]+1 AS entry_num, c.entry_time, c.value
      FROM (
          SELECT entry_time, value
            FROM table
           ORDER BY entry_time
      ) C,
      (SELECT @sample:=0) s
  ) ONE
  JOIN (
    SELECT @sample2:[email protected]+1 AS entry_num, c.entry_time, c.value
      FROM (
          SELECT entry_time, value
            FROM table
           ORDER BY entry_time
      ) C,
      (SELECT @sample2:=0) s
  ) TWO ON (TWO.entry_num - 1 = ONE.entry_num)

Nếu bạn phải thực hiện việc này trong quá trình sản xuất trên một bảng lớn, bạn có thể muốn làm điều đó cho một tập hợp con dữ liệu của mình. Ví dụ:bạn có thể làm điều đó mỗi ngày cho các mẫu của hai ngày trước đó. Điều này sẽ rất hiệu quả và cũng sẽ đảm bảo rằng bạn không bỏ qua bất kỳ mẫu bị thiếu nào ngay lúc nửa đêm. Để thực hiện việc này, các bảng ảo được đánh số thứ tự nhỏ của bạn sẽ trông giống như thế này.

  SELECT @sample:[email protected]+1 AS entry_num, c.entry_time, c.value
    FROM (
        SELECT entry_time, value
      FROM table
         ORDER BY entry_time
         WHERE entry_time >= CURRENT_DATE - INTERVAL 2 DAY
           AND entry_time < CURRENT_DATE /*yesterday but not today*/
    ) C,
    (SELECT @sample:=0) s


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ẩn ID đối tượng cơ sở dữ liệu thực trong url

  2. Sử dụng MySQLi để CHÈN Dữ liệu vào Cơ sở dữ liệu

  3. truy vấn mysqli chỉ trả về hàng đầu tiên

  4. Lỗi khung thực thể MySQL - Không thể tìm thấy nhà cung cấp cửa hàng được chỉ định trong cấu hình hoặc không hợp lệ

  5. Làm cách nào để lấy id sau khi CHÈN vào cơ sở dữ liệu MySQL bằng Python?