Đối với MySQL 8 sau đó sử dụng Trễ chức năng cửa sổ.
SELECT
test.id,
test.date,
test.number,
test.qty,
IFNULL(test.number - LAG(test.number) OVER w, 0) AS diff,
ROUND(IFNULL(test.number - LAG(test.number) OVER w, 0)/ test.qty, 2) AS 'Avg'
FROM purchases test
WINDOW w AS (ORDER BY test.`date` ASC);
Đối với phiên bản MySQL 5.7 trở xuống
Chúng tôi có thể sử dụng biến MySQL
để làm công việc này. Hãy coi tên bảng của bạn là test
.
SELECT
test.id,
test.date,
test.number,
test.qty,
@diff:= IF(@prev_number = 0, 0, test.number - @prev_number) AS diff,
ROUND(@diff / qty, 2) 'avg',
@prev_number:= test.number as dummy
FROM
test,
(SELECT @prev_number:= 0 AS num) AS b
ORDER BY test.`date` ASC;
-------------------------------------------------------------------------------
Output:
| id | date | number| qty | diff | avg | dummy |
-----------------------------------------------------------------
| 114 | 2018-10-07 | 200 | 5 | 0 | 0.00 | 200 |
| 120 | 2018-12-01 | 300 | 10 | 100 | 10.00 | 300 |
| 123 | 2019-02-03 | 700 | 12 | 400 | 33.33 | 700 |
| 1126 | 2019-03-07 | 1000 | 15 | 300 | 20.00 | 1000 |
Giải thích:
-
(SELECT @prev_number:= 0 AS num) AS b
chúng tôi đã khởi tạo biến @prev_number thành 0 trong mệnh đề FROM và được kết hợp với mỗi hàng của bài kiểm tra bảng. -
@diff:= IF(@prev_number = 0, 0, test.number - @prev_number) AS diff
Đầu tiên, chúng tôi tạo ra sự khác biệt và sau đó tạo một biến khác diff để sử dụng lại nó cho phép tính trung bình. Ngoài ra, chúng tôi đã đưa vào một điều kiện để tạo sự khác biệt cho hàng đầu tiên là 0. -
@prev_number:= test.number as dummy
chúng tôi đang đặt số hiện tại vào biến này, vì vậy, nó có thể được sử dụng cho hàng tiếp theo.
Lưu ý :Chúng tôi phải sử dụng biến này trước tiên, trong cả sự khác biệt cũng như trung bình rồi đặt thành giá trị mới để hàng tiếp theo có thể truy cập giá trị từ hàng trước.
Bạn có thể bỏ qua / sửa đổi order by
điều khoản theo yêu cầu của bạn.