Xoay bảng trong SQL: biến dòng thành cột chỉ bằng CASE

Trung cấp 5 phút đọc Cập nhật 30/07/2026 UPA AI Partner

Sếp muốn báo cáo ngang, dữ liệu lại nằm dọc. Đừng xuất Excel — bốn dòng SQL là xong.

Bài toán

Bảng điểm lưu dạng dọc: mỗi dòng là một môn. Báo cáo cần dạng ngang: mỗi môn là một cột.

DẠNG DỌCtenmondiemAnToán9An7BìnhToán6Bình8DẠNG NGANGtenToánAn97Bình68CASE + MAX

Công thức pivot

SELECT
  ten,
  MAX(CASE WHEN mon = 'Toán' THEN diem END) AS toan,
  MAX(CASE WHEN mon = 'Lý'   THEN diem END) AS ly,
  MAX(CASE WHEN mon = 'Hoá'  THEN diem END) AS hoa
FROM bang_diem
GROUP BY ten;

Ba thành phần cố định:

  1. GROUP BY cột sẽ thành dòng của bảng kết quả
  2. CASE WHEN chọn ra giá trị thuộc cột đó
  3. MAX hoặc SUM nén nhóm lại thành một dòng

Lỗi thường gặp

1. Quên hàm tổng hợp

-- Ra 4 dòng, mỗi dòng chỉ có 1 ô có giá trị
SELECT ten,
  CASE WHEN mon = 'Toán' THEN diem END AS toan,
  CASE WHEN mon = 'Lý'   THEN diem END AS ly
FROM bang_diem;

CASE chạy theo từng dòng nên không tự gom được. Phải bọc MAX và thêm GROUP BY.

2. Dùng MAX khi cần SUM

MAX đúng khi mỗi ô chỉ có một giá trị. Nếu một học sinh thi Toán hai lần, MAX chỉ lấy điểm cao hơn — có thể đúng ý, có thể không. Muốn cộng lại thì dùng SUM.

3. Thêm ELSE 0 vào chỗ không nên

-- Học sinh chưa thi Hoá sẽ hiện 0 thay vì để trống
MAX(CASE WHEN mon = 'Hoá' THEN diem ELSE 0 END)

Với đếm thì ELSE 0 là đúng. Với giá trị thì để trống (NULL) mới trung thực — 0 điểm và chưa thi là hai chuyện khác nhau.

Pivot ngược: cột thành dòng

SELECT ten, 'Toán' AS mon, toan AS diem FROM bang_ngang
UNION ALL
SELECT ten, 'Lý',   ly   FROM bang_ngang
UNION ALL
SELECT ten, 'Hoá',  hoa  FROM bang_ngang;

Đây chính là LeetCode 1795 — dạng bài xuất hiện rất nhiều trong phỏng vấn phân tích dữ liệu.

Hạn chế cần biết SQL không tự sinh cột. Bạn phải biết trước danh sách môn học và gõ ra bằng tay. Muốn số cột động thì phải sinh câu lệnh bằng ứng dụng bên ngoài.

Luyện tập

  • LeetCode 1179 — Reformat Department Table
  • LeetCode 1795 — Rearrange Products Table
  • LeetCode 1873 — Calculate Special Bonus
  • HackerRank — Occupations (pivot khó, đáng làm)

Tóm lại

  • Pivot = GROUP BY + CASE WHEN + hàm tổng hợp.
  • Thiếu MAX/SUM là ra nhiều dòng rời rạc.
  • MAX cho một giá trị mỗi ô, SUM khi cần cộng dồn.
  • ELSE 0 đúng với đếm, sai với giá trị.
  • Pivot ngược làm bằng UNION ALL.

Bạn vừa học xong xoay bảng bằng CASE

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

Làm bài tập xoay bảng bằng CASE 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 →