I'm working with PostgreSQL 13. I have two tables like this:
permission_table
name | permission |
---|---|
Ann | Read Invoice |
Ann | Write Invoice |
Ann | Execute Payments |
Bob | Read Staff data |
Bob | Modify Staff data |
Bob | Execute Payroll |
Carl | Read Invoice |
Carl | Write Invoice |
risk_table
risk_id | permission |
---|---|
Risk1 | Read Invoice |
Risk1 | Write Invoice |
Risk1 | Execute Payments |
Risk2 | Read Staff data |
Risk2 | Modify Staff data |
Risk2 | Execute Payroll |
I'd like to create a new table containing the names of the employees of the first table whose permissions are pointed as risks in the second table. After the execution, the results should be like this:
name | risk_id |
---|---|
Ann | Risk1 |
Bob | Risk2 |
Since Carl only has two of the three permissions belonging to Risk2, he will not be included in the results.
My first brute force approach was to compare the list of permissions belonging to a risk to the permissions belonging to an employee. If the first list is included in the second one, then that combination of employee/risk will be added to the results table.
INSERT INTO results_table
SELECT a.employee, b.risk_id FROM permission_table a, risk_table b WHERE
((SELECT permission FROM risk_table c WHERE b.permission = c.permission ) EXCEPT
(SELECT permission FROM permission_table d WHERE a.employee=d.employee)
) IS NULL;
I'm not sure if the results could be correct using this approach, because if the tables are big, it takes a very long time even if I add a WHERE clause limiting the query to just one employee.
Could you please help?