Cách tiếp cận của tôi cho điều này:bắt đầu với chuỗi thời gian của các quan sát và cung cấp cho mỗi quan sát một số thứ tự.
Việc đánh số sê-ri này là một vấn đề nhức nhối trong MySQL, nhưng không vấn đề gì. Đưa ra một bảng có cột ts (mục ngày giờ) và cột tạm thời, đây là truy vấn để lấy chúng với số sê-ri.
SELECT @sample:[email protected]+1 AS ser, ts, temp
FROM (
SELECT ts,temp
FROM t
ORDER BY ts
) C,
(SELECT @sample:=0) s
Hãy xem sqlfiddle này: http://sqlfiddle.com/#!2/ d81e2 / 5/0
OK, điều đó khá tầm thường. Bây giờ, giả sử chúng ta đang tìm kiếm những khoảng thời gian có nhiệt độ từ 25 độ C trở lên. Để làm điều này, chúng tôi cần cắt nhỏ chuỗi thời gian để nó bỏ qua những quan sát đó. Điều đó diễn ra như thế này:
SELECT @sample:[email protected]+1 AS ser, ts, temp
FROM (
SELECT ts,temp
FROM t
WHERE NOT temp >= 25
ORDER BY ts
) C,
(SELECT @sample:=0) s
Đây là sqlfiddle: http://sqlfiddle.com/#!2/d81e2/6 / 0
Bây giờ, mẹo tiếp theo là tìm khoảng trống thời gian trong chuỗi này. Chúng ta có thể sử dụng kỹ thuật từ bài đăng SO này để làm điều đó. Phương pháp tìm khoảng trống trong dữ liệu chuỗi thời gian trong MySQL?
Bước tiếp theo, chúng tôi kết hợp nó với chính nó.
SELECT two.ser, two.ts, two.temp,
TIMESTAMPDIFF(MINUTE, two.ts, one.ts) gap
FROM (
/* virtual table */
) ONE
JOIN (
/* same virtual table */
) TWO ON (TWO.ser+ 1 = ONE.ser)
Truy vấn này nhận được khoảng cách thời gian giữa từng mục trong chuỗi và mục sau nó. Đây là một điều đơn giản để thực hiện về mặt khái niệm, nhưng phức tạp trong phiên bản MySQL của SQL. Đây là truy vấn đầy đủ.
SELECT two.ser, two.ts, two.temp,
TIMESTAMPDIFF(MINUTE, two.ts, one.ts) gap
FROM (
SELECT @sample:[email protected]+1 AS ser, ts, temp
FROM (
SELECT ts,temp
FROM t
WHERE NOT temp >= 25
ORDER BY ts
) C,
(SELECT @sample:=0) s
) ONE
JOIN (
SELECT @sample2:[email protected]+1 AS ser, ts, temp
FROM (
SELECT ts,temp
FROM t
WHERE NOT temp >= 25
ORDER BY ts
) C,
(SELECT @sample2:=0) s
) TWO ON (TWO.ser+ 1 = ONE.ser)
Đây là sqlfiddle: http://sqlfiddle.com/#!2/d81e2/13 / 0 Lưu ý rằng một số khoảng trống có thời lượng 30 phút. Đó là điều bình thường đối với các bài đọc liên tiếp. Một số là 60 phút. Đó cũng là điều bình thường, vì chuỗi thời gian tôi đang sử dụng có một số mục nhập bị thiếu. Các mục nhập trong tập hợp kết quả này hiển thị thời gian và nhiệt độ ngay trước khoảng trống.
Vì vậy, tất cả những gì còn lại là loại bỏ các khoảng trống thừa (30 và 60 phút) và sau đó sắp xếp các khoảng trống còn lại theo thứ tự giảm dần.
SELECT two.ts, two.temp,
TIMESTAMPDIFF(MINUTE, two.ts, one.ts) gap
FROM (
SELECT @sample:[email protected]+1 AS ser, ts, temp
FROM (
SELECT ts,temp
FROM t
WHERE NOT temp >= 25
ORDER BY ts
) C,
(SELECT @sample:=0) s
) ONE
JOIN (
SELECT @sample2:[email protected]+1 AS ser, ts, temp
FROM (
SELECT ts,temp
FROM t
WHERE NOT temp >= 25
ORDER BY ts
) C,
(SELECT @sample2:=0) s
) TWO ON (TWO.ser+ 1 = ONE.ser)
WHERE TIMESTAMPDIFF(MINUTE, two.ts, one.ts)> 60
ORDER BY TIMESTAMPDIFF(MINUTE, two.ts, one.ts) DESC
Điều này cho một hàng cho mỗi chuỗi thời gian ở đó nhiệt độ trên 25 độ; lần đầu tiên lâu nhất. Mục hiển thị trong tập hợp kết quả là nhiệt độ lần cuối cùng dưới 25 trước khi tăng lên. SQL Fiddle. http://sqlfiddle.com/#!2/d81e2/14/0
Vui chứ?