Điều bạn muốn ở đây là trung bình chạy của M bản ghi trong quá khứ bắt đầu từ bản ghi hiện tại và chúng ta cần chọn bản ghi hiện tại nếu giá trị cột của bản ghi hiện tại lớn hơn giá trị trung bình đang chạy.
Đây là nỗ lực của tôi:
SET @M := 2;
SELECT * FROM
(
SELECT (@rownumber:= @rownumber + 1) AS rn, yt.*
FROM your_table yt,(SELECT @rownumber:= 0) nums
ORDER BY name, id
) a
WHERE a.var1 >
(
SELECT avg(b.var1)
FROM
(
SELECT (@rownumber:= @rownumber + 1) AS rn, yt.*
FROM your_table yt,(SELECT @rownumber:= 0) nums
ORDER BY name, id
) b
WHERE b.rn > a.rn - @M AND b.rn <= a.rn
)
@M là số bản ghi trong quá khứ được xem xét để tìm mức trung bình.
Đây là mã tại SQL Fiddle
[CHỈNH SỬA]:
Đây là một giải pháp khác mà theo tôi sẽ hiệu quả hơn truy vấn tương quan.
SET @M := 2;
SELECT a.* FROM
(
SELECT (@rownumber:= @rownumber + 1) AS rn, yt.*
FROM your_table yt,(SELECT @rownumber:= 0) nums
ORDER BY name, id
) a
JOIN
(
SELECT b.name, b.rn, AVG(c.var1) AS av
FROM
(
SELECT (@rownumber1:= @rownumber1 + 1) AS rn, yt.*
FROM your_table yt,(SELECT @rownumber1:= 0) nums
ORDER BY name, id
) b
JOIN
(
SELECT (@rownumber2:= @rownumber2 + 1) AS rn, yt.*
FROM your_table yt,(SELECT @rownumber2:= 0) nums
ORDER BY name, id
) c
ON b.name = c.name
AND c.rn > (b.rn - @M) AND c.rn <= b.rn
GROUP BY b.name,b.rn
) runningavg
ON a.name = runningavg.name
AND a.rn = runningavg.rn
AND a.var1 > runningavg.av
Ở đây tôi đã sử dụng inner join
đơn giản để tính toán mức trung bình đang chạy và một lần nữa với liên kết bên trong, hãy chọn các hàng có giá trị cột lớn hơn giá trị trung bình.
Đây là mã tại SQL Fiddle
Hãy cho tôi biết nó có được chứng minh là hiệu quả không.