No puede hacer referencia a mainMenu
mas de una vez. Y esto se debe al hecho de que en realidad tiene dos expresiones ancla, una para roles y otra para usuarios. Hay dos formas de arreglar esto. Puede dividir su consulta en dos CTE (uno para funciones y otro para usuarios). Así:
with
roleMainMenu (...)
as
(
-- role
select ...
from ....
and parentID is null
union all
select ...
from ....
inner join mainMenu on parentID = mainMenu.id
),
userMainMenu (...)
as
(
-- user
select ...
from ....
and parentID is null
union all
select ...
from ....
inner join mainMenu on parentID = mainMenu.id
)
select * from roleMainMenu
union
select * from userMainMenu
O bien, puede combinar las expresiones de anclaje de rol y usuario de antemano. No sé si la consulta para obtener elementos secundarios es genérica tanto para el rol como para los elementos del menú del usuario; de lo contrario, podría usar una expresión ancla que tenga una unión para el rol y los elementos raíz del usuario.
with mainMenu (...)
as
(
select root.* from
(
-- role roots
select .. from ... and parentID is null
union
-- user roots
select .. from ... and parentID is null
) root
union all
select ... from root
inner join mainMenu on parentID = mainMenu.id
)
select *
from mainMenu