Sau khi đã có các kiến thức căn bản về SQL, và thực hành rất nhiều bài tập, thì có lẽ giờ đây là lúc đối mặt với những câu hỏi hóc búa trong SQL.
Trong bài viết này, chúng ta sẽ cùng nhau tìm hiểu một câu hỏi được khá nhiều nhà tuyển dụng đặt ra cho các sinh viên mới ra trường. Trong đấy mình cũng đã từng bị hỏi khi phỏng vấn ở VNG, một công ty ở thời điểm hiện tại có thể nói là đáng mơ ước của rất nhiều sinh viên – Tìm nhân viên có mức lương cao thứ nhì.
Lưu ý câu hỏi trên có thể biến tấu thành các kiểu hỏi khác nhau, tuy nhiên nó vẫn có chung tình huống và cách xử lý.
Cho bảng NHANVIEN sau:
Name Salary --------------- abc 100000 bcd 1000000 efg 40000 ghi 500000
Tìm nhân viên có mức lương cao thứ nhì trong bảng NHANVIEN. Trong câu hỏi này, kết quả mong đợi của chúng ta là ‘ghi’ với mức lương 500000 thua một người đứng nhất là bcd với mức lương 1000000.
Truy vấn lồng
Đây là cách làm có vẽ hơi lôi thôi, nhưng nếu đã học kỹ phần truy vấn lồng thì có lẽ đây là giải pháp mà chúng ta nghĩ đến đầu tiên cho câu hỏi hóc búa này.
Trước hết chúng ta cần tìm ra người có mức lương cao nhất với hàm MAX trong SQL.
SELECT name, MAX(salary) as salary FROM NHANVIEN
SELECT name, MAX(salary) AS salary FROM NHANVIEN WHERE salary < (SELECT MAX(salary) FROM NHANVIEN);
Trong SQL Server, có một cách dễ dàng hơn với việc sử dụng Common Table Expression
WITH T AS ( SELECT * DENSE_RANK() OVER (ORDER BY Salary Desc) AS Rnk FROM NHANVIEN ) SELECT Name FROM T WHERE Rnk=2;
Tìm nhân viên có mức lương cao thứ ba
OK, với cách giải quyết trên thì chúng ta đã dễ dàng việc qua một câu hỏi khó rồi. Thế nhưng nếu nhà tuyển dụng là mở rộng thêm một câu tìm người có mức lương cao thứ ba thì làm sao?
Dễ mã, chúng ta lại lồng thêm một cấp nữa
SELECT name, MAX(salary) AS salary FROM NHANVIEN WHERE salary < (SELECT MAX(salary) FROM NHANVIEN WHERE salary < (SELECT MAX(salary) FROM NHANVIEN) );
Đến đây thì có vẽ không ổn, nếu người ta bảo tìm người có mức lương cao thứ 100 thì ăn hành. Bắt buộc chúng ta phải tìm ra một giải pháp cho vấn đề này.
Hay quá, thật ra có một cách dễ dàng hơn rất nhiều thay vì sử dụng truy vấn lồng đó là sử dụng LIMIT, OFFSET kết hợp với ORDER BY.
Xem nào, chúng ta chỉ cần sắp xếp các nhân viên theo mức lương giảm dần, sau đó bỏ qua 2 nhân viên đầu tiên có mức lương cao thứ nhất và thứ nhì với OFFSET và chỉ lấy một nhân viên tiếp theo thì đó chính là người có mức lương cao thứ ba.
SELECT salary FROM NHANVIEN ORDER BY salary desc limit n-1,1
Trong đó chúng ta cần làm rõ cú pháp LIMIT
SELECT select_list FROM table_name LIMIT [offset,] row_count;
Với
- Offset (tuỳ chọn, có thể có hoặc không) chỉ định số dòng đầu tiên bị bỏ qua trong kết quả trả về.
- row_count: Là số dòng dữ liệu tối đa được lấy trong kết quả trả về
Từ đó chúng ta có thể dễ dàng tìm ra người có mức lương cao thứ 4 áp dụng phương pháp ở trên.
SELECT * FROM NHANVIEN WHERE salary= (SELECT DISTINCT(salary) FROM NHANVIEN ORDER BY salary LIMIT 3,1);
Công thức tổng quát
Cho N là số thứ tự xếp hạng của mức lương của nhân viên. Để tìm nhân viên có mức lương cao thứ N chúng ta có công thức sau:
SELECT * FROM employee WHERE salary= (SELECT DISTINCT(salary) FROM employee ORDER BY salary LIMIT n-1,1);
Nguồn tham khảo
https://www.mysqltutorial.org/mysql-limit.aspx
https://www.geeksforgeeks.org/sql-query-to-find-second-largest-salary/