Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

Mô phỏng hàm LAG trong MySQL (trước version 8.0)

Tóm tắt

Trước MySQL 8.0 không có hàm window LAG(). Bài viết示范用 biến người dùng (@f, @s) và self-join để tính tỷ lệ giữa hàng hiện tại và hàng trước (lag 1).

Ví dụ dữ liệu

CREATE TABLE LagDemo (UserId INT, UserValue INT);
INSERT INTO LagDemo VALUES
(12,158), (18,756), (15,346), (87,646),
(27,334), (90,968), (84,378), (85,546);

Truy vấn mô phỏng LAG

SET @f := 0;
SET @s := 2;

SELECT l1.UserId, l1.UserValue, 
       l1.UserValue / l2.UserValue AS `LAG`
FROM (
    SELECT IF(@f, @f := @f + 1, @f := 1) AS RowNumber, UserId, UserValue
    FROM LagDemo
) AS l1
LEFT JOIN (
    SELECT IF(@s, @s := @s + 1, @s := 1) AS RowNumber, UserId, UserValue
    FROM LagDemo
) AS l2 ON l1.RowNumber = l2.RowNumber;

Kết quả

+--------+-----------+--------+
| UserId | UserValue | LAG    |
+--------+-----------+--------+
| 12     | 158       | NULL   |
| 18     | 756       | NULL   |
| 15     | 346       | 2.1899 |
| 87     | 646       | 0.8545 |
| 27     | 334       | 0.9653 |
| 90     | 968       | 1.4985 |
| 84     | 378       | 1.1317 |
| 85     | 546       | 0.5640 |
+--------+-----------+--------+

Giải thích kỹ thuật

  • @f bắt đầu từ 0, tăng 1 mỗi hàng → đánh số thứ tự 1,2,3...
  • @s bắt đầu từ 2, tăng 1 mỗi hàng → đánh số 2,3,4...
  • Join trên RowNumber khiến hàng 1 join với hàng 2, hàng 2 join với hàng 3... → tạo hiệu ứng LAG 1.
  • Hai hàng đầu tiên không có hàng trước → NULL.

Khuyên dùng MySQL 8.0+

SELECT UserId, UserValue,
       UserValue / LAG(UserValue) OVER (ORDER BY UserId) AS LAG
FROM LagDemo;

Cách này chuẩn SQL, dễ đọc, hiệu năng tốt hơn, không phụ thuộc thứ tự vật lý.