Skip to content
Advertisement

Join repeatedly until a string is present?

While querying a subset of our employees, I’m trying to add a field for the SVP they “roll up” to.

Employees may have anywhere from 1 to 5 or 6 degrees of separation from their SVP. The trouble is, we don’t have any specific hierarchical indicator to reference. I have to do this by walking up through the employee’s manager repeatedly, until some manager’s manager has “SVP” in their title.

How could I write a query to do this?

From the opposite direction, I’ve found the employees of a specific SVP (named BM for the example) by saying, ‘Employee’s manager is BM, OR Employee’s manager’s manager is BM, OR Employee’s manager’s manager’s manager is BM’ and so on…

For my instance, I suspect I’d only use the same sys_user table over and over again, following the manager field each time until I reach a user with SVP in the title.

I appreciate any helps or tip that can be offered. Thanks for looking and have a great day.

Advertisement

Answer

Your Sys_User table is an adjacency list that only provides information about employees and who they directly report to. Adjacency Lists are one way to to encode hierarchical data. They’re nice because they’re relatively fast and compact, however they aren’t the only way to encode hierarchical relationships.

To answer the questions you are asking you will benefit from re-encoding the data into a Closure table which maps each employee to all of its direct and indirect managers/reportees along with their degree of separation, and any other additional pertinent info. However, since it represents a Many-to-Many relationship you don’t want to over load it with too much additional data. Fortunately thanks to the utility of recursive queries you can create one fairly easily on the fly.

To create a closure table you start by populating it with the degree 0 relationships, where every employee is considered their own manager/reportee. The reasoning for it is a bit beyond my ken, but it has something to do with the mathematics behind the concept of transitive closure (hence the name closure table). After that you iteratively (recursively) add each additional reporting degree. You can either do that from the Top Down, or from the Bottom Up

Here’s the Top Down version:

And here’s the Bottom Up version:

It doesn’t matter too much which version you use if you are going to generate the entire closure table, however, if you want to optimize your query and only generate a partial closure table then it depends on if you want to walk up or down the tree.

Once generated you can use the closure table to answer your questions about SVPs such as who each contractor’s SVP is:

sys_id | name         | title      | degree | SVP_ID | SVP_name          | SVP_title
-----: | :----------- | :--------- | -----: | -----: | :---------------- | :--------
555789 | Tina Belcher | Contractor |      2 | 654321 | Calvin Fischoeder | SVP      

Or every direct and indirect report to the SVP named Calvin Fischoeder:

manager_id | name              | title | degree | report_id | report_name       | report_title
---------: | :---------------- | :---- | -----: | --------: | :---------------- | :-----------
    654321 | Calvin Fischoeder | SVP   |      0 |    654321 | Calvin Fischoeder | SVP         
    654321 | Calvin Fischoeder | SVP   |      1 |    123456 | Bob Belcher       | Manager     
    654321 | Calvin Fischoeder | SVP   |      2 |    555789 | Tina Belcher      | Contractor  

To see all queries in action, check out this db<>fiddle

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement