I have 5 SQL tables with columns as follows:
tbl_request_listEmpB
listEmpB_id request_id
tbl_request_listEmpD
listEmpD_id request_id
tbl_employee
id, parent_id (this one refers to id in tbl_department)
tbl_department
id, parent_id (that one referes to id of parent department)
tbl_department_manager
department_id, manager_employee_id
As input data I have employee_id
and request_id
.
I need to figure out whether the employee has access to the request (whether he's a manager or not)
Here's the query which is supposed to return 1 if the current user is a manager, 0 otherwise
with reqEmployees as (
select listEmpB_id as employee_id
from tbl_request_listEmpB
where request_id = ${request_id}
union all --concatenate the two tables
select listEmpD_id
from tbl_request_listEmpD
where request_id = ${request_id}
),
cte as (
select e.parent_id, null as parent_id
from reqEmployees r
join tbl_employee e on e.id = r.employee_id -- get these employees' departments
union all
select d.id, d.parent_id
from cte
join tbl_department d on d.id = cte.parent_id -- and get parent departments
)
select case when exists (select 1
from cte
join tbl_department_manager dm on dm.department_id = cte.id
where dm.manager_employee_id = ${employee_id})
then 1 else 0 end;
Finally, there's the logic that I believe is implemented in the query above:
- First we need to identify whether the
employee_id
is a manager or not. If he is - find in which departments. So we query totbl_department_manager
based onmanager_employee_id(=employee_id from input data)
to get a list of correspondingdepartment_id
and store them in a variable. If the query returned 0 departments - terminate and return false - Based on
request_id
we collect ids of employees from bothtbl_request_listEmpB
andtbl_request_listEmpD
. Later we refer to them asemployee_id
fromreqEmployees
- Query to
tbl_employee
based on ids retrieved from p.2 to getparent_id
(list of unique departments employees belong to) - If there's a match between at least one department from p.1 and a one from p.3 return true
- If not, there's a need to query to
tbl_department
and recursively search for a match between at least one element from p.1 and one element in p.3.parent_id
Here's what I mean
Consider the following chart
And here's the corresponding SQL table:
tbl_department (id, parent_id)
dep0 null
dep1 dep0
dep2 dep1
dep3 dep1
dep4 dep2
dep5 dep0
So, if we have a departments list returned from p.1 of ['dep1']
(there might be more than one element, we have to iterate through each element) we need to return true ONLY if from p.3 we've got dep1|dep2|dep3|dep4 - (dep1 descendants including dep1)
. If ['dep2']
return true if dep2|dep4
. So there should at least one match of at least one element from p.1 and recursive result from p.5. I hope I illustrated it in the clearest way possible
Almost forgot - the query above gives me
"Column "parent_id" for "cte" is specified more than once"
But I don't think that it does what it's supposed to do, I need to rewrite it
Any help would be greatly appreciated