Để 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