Tác giả: Lê Trung Kiên lớp java 08
Email: lekien.2803.cg@gmail.com
SĐT: 0942096947
Link bài toán: https://leetcode.com/problems/employees-earning-more-than-their-managers/

1. Mở đầu

Xin chào các bạn, mình viết ra bài viết này để chia sẻ phương pháp giải cũng như tư duy của mình về bài toán này của leetcode. Phương pháp của mình có thể không phải là tối ưu nhất, tuy nhiên mình sẽ phân tích, chia nhỏ bài toán ra thành các module nhỏ hơn để dễ giải quyết cũng như giúp các bạn hiểu được các yêu cầu mà bài toán đưa ra.

2. Đề bài

Cho bảng Employee:

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| name        | varchar |
| salary      | int     |
| managerId   | int     |
+-------------+---------+
id là cột khóa chính cho bảng này.
Mỗi hàng của bảng này cho biết ID của nhân viên, tên, mức lương và ID của người quản lý của họ.

Viết truy vấn SQL để tìm những nhân viên kiếm được nhiều tiền hơn người quản lý của họ.
Trả về bảng kết quả theo thứ tự bất kỳ.
Định dạng kết quả truy vấn nằm trong ví dụ sau.

Ví dụ:

Input: 
Employee table:
+----+-------+--------+-----------+
| id | name  | salary | managerId |
+----+-------+--------+-----------+
| 1  | Joe   | 70000  | 3         |
| 2  | Henry | 80000  | 4         |
| 3  | Sam   | 60000  | Null      |
| 4  | Max   | 90000  | Null      |
+----+-------+--------+-----------+
Output: 
+----------+
| Employee |
+----------+
| Joe      |
+----------+
Explanation: Joe is the only employee who earns more than his manager.

3. Phân tích

Bài này chúng ta phải thực hiện so sánh số tiền lương của hai người, nhưng lại ở cùng một bảng. Để giải quyết vấn đề này chúng ta sẽ sử dụng SELF JOIN. Để sử dụng SELF-JOIN, bảng được sử dụng phải của một cột (tạm gọi là X) hoạt động như 1 primary key và một cột khác (gọi là Y) chứa dữ liệu có liên kết với cột X. Giá trị trong 2 cột X và Y này không nhất thiết phải giống nhau và giá trị tại cột Y thậm chí còn có thể là NULL.
Hãy nhìn vào ví dụ, ta thấy:
Mỗi một nhân viên (employee) sẽ có ID cá nhân riêng (cột X) và được quản lý bởi một người quản lý cũng thuộc danh sách nhân viên đó. Người quản lý này được gắn cho một mã định danh của quản lý là managerID (cột Y) có giá trị trùng khớp với EmployeeID. Ta có thể thấy một vài mối quan hệ trong bảng như sau:

  • Nhân viên Joe có mã ID là 1, còn người quản lí của Joe là Sam có mã ID là 3.

  • Nhân viên Henry có mã ID là 2, người quản lí của anh ta là Max có mã ID là 4.

  • Còn Sam và Max không có quản lí, nên cột managerID của họ là NULL.

    Chúng ta sẽ sử dụng cú pháp SELF JOIN như sau:

SELECT a.ten_cot, b.ten_cot
FROM bang1 a, bang1 b
WHERE a.cot_chung = b.cot_chung

Tuy nhiên với cú pháp trên, chúng ta mới chỉ lấy ra được tên của nhân viên có quản lí của mình mà thôi:

| employee |
| -------- |
| Joe      |
| Henry    |

Chúng ta sẽ phải thêm một điều kiện nữa ấy là so sánh lương của nhân viên với quản lí của họ.

4. Code bằng máy

Code của chúng ta như sau:

select a.name as 'employee'
from employee as a, employee as b
where a.managerid = b.id and a.salary > b.salary

6. Kết thúc

Qua bài viết này, mình đã chia sẻ cho các bạn cách mình tư duy khi giải bài tập trên leetcode. Hi vọng bài viết giúp ích cho các bạn trong cách tư duy để giải các bài tập khác. Xin cám ơn các bạn đã dành thời gian đọc và theo dõi. Peace!!!