JuniorLập trìnhSQL
Viết query liệt kê mỗi nhân viên cùng tên manager của họ
Thử trả lời trước
Đáp án mẫu
Manager cũng chỉ là một dòng khác trong cùng bảng, nên hãy join bảng với chính nó. Self join cần hai alias khác nhau để database biết mỗi cột đến từ bản sao nào.
SELECT e.name AS employee,
m.name AS manager
FROM employees e
LEFT JOIN employees m ON m.id = e.manager_id
ORDER BY e.name;
Hãy đọc nó như hai vai trò: e là nhân viên, m là dòng manager mà e.manager_id trỏ tới.
LEFT JOIN rất quan trọng. CEO có manager_id = NULL nên không có dòng khớp. INNER JOIN sẽ âm thầm loại nhân viên đó, còn LEFT JOIN giữ dòng và hiển thị manager là NULL.
Cùng mẫu này trả lời được các câu hỏi liên quan, ví dụ nhân viên có lương cao hơn manager:
SELECT e.name
FROM employees e
JOIN employees m ON m.id = e.manager_id
WHERE e.salary > m.salary;
Self join phù hợp với một cấp của cây. Với độ sâu bất kỳ, hãy dùng recursive CTE.
Ý chính
- Self join dùng cùng một bảng hai lần với alias khác nhau
- Join employee.manager_id với manager.id
- LEFT JOIN giữ nhân viên không có manager
- Recursive CTE xử lý độ sâu không giới hạn
Câu hỏi nối tiếp thường gặp
- Làm sao liệt kê manager không có nhân viên trực tiếp?
Lỗi thường gặp
- Dùng INNER JOIN và mất người đứng đầu cây
- Quên alias và gặp lỗi ambiguous column