Giới thiệu
Kỹ thuật cũ (pre-MySQL 8.0) dùng biến phiên @var kết hợp CROSS JOIN bảng dẫn xuất khởi tạo biến để tính running total theo thứ tự giá trị.
Ví dụ thực hành
1. Tạo bảng DemoTable
mysql> CREATE TABLE DemoTable (Value INT);
2. Chèn dữ liệu
mysql> INSERT INTO DemoTable VALUES (50),(20),(30);
3. Running total sắp xếp theo Value
mysql> SELECT t.Value, (@s := @s + t.Value) AS Number
FROM DemoTable t
CROSS JOIN (SELECT @s := 0) p
ORDER BY t.Value;
4. Kết quả (theo Value: 20, 30, 50)
+-------+--------+
| Value | Number |
+-------+--------+
| 20 | 20 |
| 30 | 50 |
| 50 | 100 |
+-------+--------+
Giải thích
CROSS JOIN (SELECT @s := 0) p: Tạo bảng dẫn xuất 1 hàng để khởi tạo biến@s = 0trước khi quétDemoTable.ORDER BY t.Value: Đảm bảo thứ tự tính toán (20 → 30 → 50).@s := @s + t.Value: Gán và trả về giá trị mới.
⚠️ Vấn đề với biến phiên
- Thứ tự đánh giá không đảm bảo trong các phiên bản/MySQL optimizer khác nhau.
- Không hoạt động đúng trong một số trường hợp (subquery, view, prepared statement).
- Deprecated trong MySQL 8.0 (cảnh báo), có thể bị xóa tương lai.
Cách hiện đại (MySQL 8.0+): Window Function
SELECT Value, SUM(Value) OVER (ORDER BY Value) AS RunningTotal
FROM DemoTable;
- Chuẩn SQL:2003.
- An toàn, tối ưu, hỗ trợ
PARTITION BY,ROWS/RANGE BETWEEN. - Hiệu suất tốt hơn (không cần user variable).
Khuyến nghị
Luôn dùng Window Function (SUM() OVER) cho MySQL 8.0+. Chỉ dùng biến phiên nếu bắt buộc chạy trên MySQL 5.7 hoặc cũ hơn.