Giới thiệu
Bài toán: Lấy các hàng mà tổng cộng dồn của Amount (theo thứ tự Amount tăng dần) chưa vượt quá 150. Sử dụng subquery tương quan (correlated subquery) để tính tổng tích lũy cho từng hàng.
Ví dụ thực hành
1. Tạo bảng DemoTable844
mysql> CREATE TABLE DemoTable844 (
Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Amount INT
);
2. Chèn dữ liệu
mysql> INSERT INTO DemoTable844(Amount) VALUES (80),(100),(60),(40),(150),(24);
3. Truy vấn: tổng Amount của các hàng có Amount <= Amount hiện tại < 150
mysql> SELECT * FROM DemoTable844 tbl
WHERE (SELECT SUM(Amount) FROM DemoTable844
WHERE Amount <= tbl.Amount ORDER BY Amount) < 150
ORDER BY Id;
4. Kết quả
+----+--------+
| Id | Amount |
+----+--------+
| 3 | 60 |
| 4 | 40 |
| 6 | 24 |
+----+--------+
Giải thích logic
- Với hàng Amount=24: tổng các Amount <= 24 là 24 (< 150) → giữ.
- Với hàng Amount=40: tổng (24+40)=64 (< 150) → giữ.
- Với hàng Amount=60: tổng (24+40+60)=124 (< 150) → giữ.
- Với hàng Amount=80: tổng (24+40+60+80)=204 (>= 150) → loại.
Cách hiện đại (MySQL 8.0+): Window Function
SELECT Id, Amount
FROM (
SELECT Id, Amount,
SUM(Amount) OVER (ORDER BY Amount ROWS UNBOUNDED PRECEDING) AS running_sum
FROM DemoTable844
) t
WHERE running_sum < 150
ORDER BY Id;
Cách này rõ ràng, hiệu suất tốt hơn, và dễ mở rộng (ví dụ thêm PARTITION BY).
Lưu ý
- Subquery tương quan chạy chậm trên bảng lớn (O(N²)).
- Cần index trên
Amountđể subquery nhanh hơn. - Yêu cầu sắp xếp rõ ràng trong subquery (
ORDER BY Amount) để tổng tích lũy đúng logic.