-- DDL: Create the Employee table CREATE TABLE employees ( employee_id INT PRIMARY KEY, employee_name VARCHAR(100) NOT NULL, manager_id INT, CONSTRAINT fk_manager FOREIGN KEY (manager_id) REFERENCES employees(employee_id) );
-- Sample Data: Populate the Employee table INSERT INTO employees (employee_id, employee_name, manager_id) VALUES (1, 'Alice CEO', NULL), (2, 'Bob VP Sales', 1), (3, 'Charlie VP Marketing', 1), (4, 'David Sales Director', 2), (5, 'Eve Marketing Director', 3), (6, 'Frank Sales Rep', 4), (7, 'Grace Sales Rep', 4), (8, 'Heidi Marketing Specialist', 5), (9, 'Ivan Marketing Specialist', 5), (10, 'Judy Sales Rep', 2); -- Direct report to VP, not a director
-- Recursive CTE Query: Build the Organizational Hierarchy WITH RECURSIVE OrgHierarchy AS ( -- Anchor Member: Select the root employee(s) SELECT e.employee_id, e.employee_name, e.manager_id, 1 AS hierarchy_level, CAST(e.employee_name AS TEXT) AS full_path -- Use TEXT for path for portability FROM employees e WHERE e.manager_id IS NULL UNION ALL -- Recursive Member: Join employees to their managers SELECT e.employee_id, e.employee_name, e.manager_id, oh.hierarchy_level + 1 AS hierarchy_level, CAST(oh.full_path || ' > ' || e.employee_name AS TEXT) AS full_path -- Use || for concatenation (PostgreSQL/MySQL) FROM employees e INNER JOIN OrgHierarchy oh ON e.manager_id = oh.employee_id ) -- Final Selection from the CTE SELECT employee_id, employee_name, manager_id, hierarchy_level, full_path FROM OrgHierarchy ORDER BY full_path;
-- Expected Query Plan Notes: -- The query plan for a recursive CTE typically involves an initial scan for the anchor member, followed by iterative steps for the recursive member. Each iteration processes the results from the previous step, joining them back to the base table. This often manifests as a "Concatenation" or "Union All" operator combining the anchor and recursive parts. Performance is heavily dependent on efficient lookups for the manager_id in the recursive step. Without proper indexing, each recursive step could result in a full table scan, leading to significant performance degradation as the hierarchy depth or breadth increases. Temporary tables or worktables are often used internally by the database engine to store intermediate results during the recursion.
-- Index Recommendation: -- To optimize the recursive join operation, an index on the manager_id column is crucial. This allows the database to quickly find all direct reports for a given manager, making each recursive step efficient. CREATE INDEX idx_manager_id ON employees (manager_id);