Reputation: 281
I have a little problem to make a recursive query and I can’t to extract the data which I need.
I have 3 tables (menu, type_role, privilege)
menu ---------------------------------------------------------- | id| parent_id | tittle | controller | action | | 1 | | Users | | | | 2 | 1 | Create User | users | create | | 3 | 1 | Edit User | users | edit | | 4 | 1 | Show Users | users | show | | 5 | | Contacts | | | | 6 | 5 | Create Contacs | contacts | create | | 7 | 5 | Edit Contacts | contacts | edit | | 8 | | Inventory | | | | 9 | 8 | Register Piece | pieces | register | | 10| 8 | Show Pieces | pieces | show |
type_role --------------------- | id| role | | 1 | Administrator | | 2 | Technical | | 3 | Operator |
privilege --------------------- | role_id | menu_id | | 1 | 2 | | 1 | 3 | | 1 | 4 | | 1 | 6 | | 1 | 7 | | 1 | 9 | | 1 | 10 | | 2 | 9 | | 2 | 10 | | 3 | 6 | | 3 | 7 | | 3 | 10 |
I need to extract:
id, parent_id, controller, action where the id of the type of role equals 1
I made the query and I get the data, but the query extract it parents who are not related to the type of user and I don't need this.
I just want to extract all the menu items and their parent by user type
SELECT menu.id,menu.parent_id,menu.controller,menu.action
FROM privilege
INNER JOIN menu ON
menu.id = privilege.menu_id
INNER JOIN type_role ON
type_role.id = privilege.role_id
WHERE type_role.id = 1
UNION
SELECT menu_recur.id,menu_recur.parent_id,menu_recur.menu_recur,menu_recur.action
FROM menu menu_recur
INNER JOIN menu menutwo ON
menu_recur.id = menutwo.parent_id
I think I should use WITH RECURSIVE but I have not worked with this kind of recursive queries
Upvotes: 2
Views: 479
Reputation: 238216
Here's a recursive query that loops up the parent entries.
with recursive list as
(
select menu.id, parent_id, tittle, controller, action
from menu
join privilege
on menu.id = privilege.menu_id
join type_role
on type_role.id = privilege.role_id
where type_role.role = 'Technical'
union all
select menu.id, menu.parent_id, menu.tittle, menu.controller, menu.action
from list
join menu
on menu.id = list.parent_id
)
select distinct *
from list
order by
id
;
This prints:
id | parent_id | tittle | controller | action
----+-----------+----------------+------------+----------
8 | | Inventory | |
9 | 8 | Register Piece | pieces | register
10 | 8 | Show Pieces | pieces | show
(3 rows)
See it working at SQL Fiddle. The example is for Technical
, as Administrator
includes every row.
Upvotes: 1