Để bắt đầu, hãy cho 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 đăng nhập một vài thứ sáu phút (mười lần một giờ), tất cả giá trị 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ó 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 lấy số phút và giây ra.
Điều này có hiệu quả hợp lý và sẽ giúp bạn bắt đầu. Nó 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 bạn và hạn chế truy vấn của bạn, ví dụ, 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 không thể phát hiện toàn bộ số giờ đi kèm với các mẫu bị thiếu. Nó cũng là một chút nhạy cảm với jitter trong mẫu của bạn. Tức là, nếu mẫu hàng đầu của bạn đôi khi sớm hơn nửa giây (10:59:30) và đôi khi trễ nửa giây (11:00:30) số lượng tóm tắt hàng giờ của bạn sẽ bị tắt. Vì vậy, điều tóm tắt giờ này (hoặc tóm tắt ngày, hoặc tóm tắt phút, vv) không phải là chống đạn.
Bạn cần truy vấn tự tham gia để hoàn thành công việc một cách hoàn hảo; đó là một chút của một hairball và không gần như là 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 phụ) như thế này với các mẫu được đánh số. (Đây là một nỗi đau 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 tự tham gia.
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 hàng hai bảng tiếp theo được bù trừ bởi một mục 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 số lớn hơn ngưỡng của bạn interval
và có thời gian của mẫu ngay trước các giá trị bị thiếu.
Hơn tất cả truy vấn tự tham gia là điều này. Tôi đã nói với bạn đó là một viên bi.
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 làm điều này trong 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 bạn. 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 bạn không bỏ qua bất kỳ mẫu bị thiếu nào vào lúc nửa đêm. Để làm điều này, các bảng ảo nhỏ của bạn sẽ trô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
Làm cách nào để xác định khoảng cách? Bạn có một giới hạn khó khăn về thời gian có thể trôi qua giữa các đầu vào không? –
Biến Y. Quên để xác định điều đó. – TheDog