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

Tính tổng tích lũy (running total) với CROSS JOIN và biến phiên trong MySQL

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 = 0 trước khi quét DemoTable.
  • 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.