Thêm một chữ ORDER BY và SUM của bạn đổi hẳn ý nghĩa

Nâng cao 5 phút đọc Cập nhật 30/07/2026 UPA AI Partner

Cùng một hàm SUM. Có ORDER BY thì ra luỹ kế, không có thì ra tổng cả nhóm. Không ai nói cho bạn biết.

Bài toán

Biểu đồ cần đường doanh thu luỹ kế từ đầu tháng, và đường trung bình trượt 3 ngày để làm mượt.

GOCngaydoanh_thu01100028003120SAU OVERngaydoanh_thuluy_ketb_3_ngay0110010010002801809003120300100SUM OVER (ORDER BY)

Luỹ kế

SELECT
  ngay,
  doanh_thu,
  SUM(doanh_thu) OVER (ORDER BY ngay) AS luy_ke
FROM doanh_thu_ngay;
Chi tiết quyết định tất cả SUM(x) OVER () cho tổng toàn bộ.
SUM(x) OVER (ORDER BY ngay) cho luỹ kế đến dòng hiện tại.
Chỉ khác một mệnh đề, ý nghĩa khác hẳn.

Trung bình trượt

SELECT
  ngay,
  ROUND(AVG(doanh_thu) OVER (
    ORDER BY ngay
    ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
  ), 1) AS tb_3_ngay
FROM doanh_thu_ngay;

ROWS BETWEEN định nghĩa “cửa sổ” — bao nhiêu dòng được tính vào:

ViếtNghĩa
2 PRECEDING AND CURRENT ROW3 dòng gần nhất
UNBOUNDED PRECEDING AND CURRENT ROWtừ đầu đến hiện tại (mặc định)
1 PRECEDING AND 1 FOLLOWINGtrước, hiện tại, sau
CURRENT ROW AND UNBOUNDED FOLLOWINGtừ hiện tại đến hết

Lỗi thường gặp

1. Nhầm ROWS với RANGE

ROWS đếm số dòng. RANGE đếm theo giá trị, nên mọi dòng cùng ngày được gộp vào một bậc. Với dữ liệu có ngày trùng, hai cách cho kết quả khác nhau. Mặc định là RANGE — đây là nguồn gốc của nhiều con số khó hiểu.

2. Quên PARTITION BY

-- SAI: luỹ kế chạy xuyên qua mọi thành phố
SUM(doanh_thu) OVER (ORDER BY ngay)

-- ĐÚNG
SUM(doanh_thu) OVER (PARTITION BY thanh_pho ORDER BY ngay)

3. Ngày bị thiếu làm trung bình trượt sai

ROWS 2 PRECEDING lấy 3 dòng, không phải 3 ngày. Nếu thiếu ngày, cửa sổ trượt qua khoảng trống mà không ai biết. Tạo dải ngày đầy đủ trước khi tính.

Mẹo viết gọn khi dùng lại nhiều lần

SELECT
  ngay,
  SUM(doanh_thu) OVER w      AS luy_ke,
  AVG(doanh_thu) OVER w      AS trung_binh,
  MAX(doanh_thu) OVER w      AS cao_nhat
FROM doanh_thu_ngay
WINDOW w AS (ORDER BY ngay);

Luyện tập

  • LeetCode 1321 — Restaurant Growth (trung bình trượt 7 ngày)
  • LeetCode 579 — Find Cumulative Salary of an Employee
  • LeetCode 1204 — Last Person to Fit in the Bus
  • LeetCode 534 — Game Play Analysis III
  • HackerRank — Weather Observation Station 20 (median)

Tóm lại

  • ORDER BY trong OVER biến SUM thành luỹ kế.
  • ROWS BETWEEN định nghĩa cửa sổ trung bình trượt.
  • ROWS đếm dòng, RANGE đếm theo giá trị — mặc định là RANGE.
  • Nhiều nhóm thì phải có PARTITION BY.
  • Dùng WINDOW w AS (…) khi lặp lại cùng một cửa sổ.

Bạn vừa học xong luỹ kế và trung bình trượt

Sẵn sàng luyện tập chưa?

Làm bài tập luỹ kế và trung bình trượt trên dữ liệu thật, chấm điểm ngay khi bạn bấm chạy.

Bắt đầu luyện tập →