Phỏng vấn SQL: JOIN, GROUP BY, subquery và index qua ví dụ dễ hiểu

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

SQL là kỹ năng được hỏi trong gần như mọi vị trí liên quan đến dữ liệu, từ backend đến phân tích. Các câu hỏi thường không quá phức tạp nhưng yêu cầu bạn viết đúng và giải thích rõ. Hãy cùng ôn các dạng bài hay gặp với hai bảng ví dụ: customers và orders.

Các loại JOIN

  • INNER JOIN: chỉ lấy dòng có khớp ở cả hai bảng.
  • LEFT JOIN: lấy tất cả dòng bảng trái, dòng không khớp bên phải sẽ là NULL.
  • RIGHT JOIN: ngược lại với LEFT JOIN.
  • FULL JOIN: lấy tất cả dòng của cả hai bảng (không phải hệ quản trị nào cũng hỗ trợ trực tiếp).
SELECT c.name, o.id, o.totalFROM customers cLEFT JOIN orders o ON o.customer_id = c.id;

Tìm khách hàng chưa từng mua hàng

SELECT c.id, c.nameFROM customers cLEFT JOIN orders o ON o.customer_id = c.idWHERE o.id IS NULL;

Đây là một cách dùng LEFT JOIN rất phổ biến để tìm bản ghi không có quan hệ.

GROUP BY, HAVING và hàm tổng hợp

SELECT customer_id, COUNT(*) AS so_don, SUM(total) AS tong_tienFROM ordersGROUP BY customer_idHAVING COUNT(*) >= 3ORDER BY tong_tien DESC;

WHERE lọc dòng trước khi nhóm, còn HAVING lọc sau khi nhóm, dựa trên kết quả hàm tổng hợp. Đây là câu hỏi quen thuộc: vì sao không dùng được COUNT(*) trong WHERE.

Thứ tự thực thi logic của truy vấn

  1. FROM và JOIN
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. SELECT
  6. ORDER BY
  7. LIMIT

Hiểu thứ tự này giúp bạn giải thích vì sao bí danh khai báo trong SELECT không dùng được trong WHERE ở nhiều hệ quản trị.

Subquery và CTE

Subquery là truy vấn lồng bên trong truy vấn khác. CTE (Common Table Expression) dùng WITH để đặt tên cho một truy vấn tạm, giúp câu lệnh dễ đọc hơn.

WITH tong AS (  SELECT customer_id, SUM(total) AS tong_tien  FROM orders  GROUP BY customer_id)SELECT c.name, t.tong_tienFROM tong tJOIN customers c ON c.id = t.customer_idWHERE t.tong_tien > 1000000;

Bài kinh điển: dòng có giá trị lớn thứ hai

SELECT MAX(total)FROM ordersWHERE total < (SELECT MAX(total) FROM orders);

Nếu hệ quản trị hỗ trợ hàm cửa sổ, bạn có thể dùng DENSE_RANK() OVER (ORDER BY total DESC) để mở rộng sang hạng thứ n.

Index và khi nào nên dùng

Index giúp tìm kiếm nhanh hơn như mục lục của một cuốn sách, nhưng làm chậm thao tác ghi và tốn dung lượng. Nên tạo index cho các cột thường xuất hiện trong WHERE, JOIN, ORDER BY. Index nhiều cột phụ thuộc thứ tự cột: index trên (a, b) giúp truy vấn lọc theo a hoặc a và b, nhưng không giúp truy vấn chỉ lọc theo b. Dùng lệnh EXPLAIN để xem kế hoạch thực thi và kiểm tra index có được dùng không.

DELETE, TRUNCATE và DROP

  • DELETE: xóa dòng theo điều kiện, có thể hoàn tác trong giao dịch.
  • TRUNCATE: xóa toàn bộ dòng nhanh, giữ cấu trúc bảng.
  • DROP: xóa luôn bảng.

Transaction và tính chất ACID

Transaction là nhóm thao tác được xem như một đơn vị: hoặc thành công hết, hoặc hủy hết. Bốn tính chất ACID gồm nguyên tử (Atomicity), nhất quán (Consistency), cô lập (Isolation) và bền vững (Durability). Ví dụ kinh điển là chuyển tiền: trừ tiền tài khoản A và cộng tiền tài khoản B phải cùng thành công, nếu bước hai lỗi thì bước một phải được hoàn tác.

START TRANSACTION;UPDATE accounts SET balance = balance - 100 WHERE id = 1;UPDATE accounts SET balance = balance + 100 WHERE id = 2;COMMIT;

Các lỗi thường gặp khi viết SQL trong phỏng vấn

  • Quên điều kiện ON khiến phép nối thành tích Descartes, trả về số dòng khổng lồ.
  • Dùng = NULL thay vì IS NULL; so sánh với NULL không bao giờ đúng bằng dấu bằng.
  • Dùng SELECT * trong mã sản phẩm thay vì liệt kê cột cần thiết.
  • Chọn cột không nằm trong GROUP BY và không phải hàm tổng hợp.
  • Không ghi chú giả định khi đề bài chưa rõ, ví dụ cách xử lý giá trị NULL hoặc trùng lặp.

Khi làm bài trực tiếp, hãy nói thành tiếng suy nghĩ của bạn, bắt đầu từ truy vấn đơn giản rồi thêm dần điều kiện. Người phỏng vấn thường quan tâm quá trình tư duy không kém kết quả cuối.

Kết luận

Hãy tự dựng một cơ sở dữ liệu nhỏ, nhập vài chục dòng và luyện viết các truy vấn trên. Khi bạn tự thấy kết quả thay đổi theo từng thay đổi của truy vấn, các khái niệm sẽ in sâu hơn nhiều so với chỉ đọc.

Để học SQL và thiết kế cơ sở dữ liệu có hệ thống, bạn có thể xem các khóa học tại codebem.com.

author_photo
Nguyễn Đình Cường

0 comment