我在构建查询时遇到问题,需要帮助。请考虑以下MYSQL表。
用户表
username
tuser
tman
tester
usergrouplink table
username|groupname
tuser |grp1
tuser |grp2
组表
groupname|reporter|provisioner|manager
grp1 |0 |0 |1
grp2 |0 |1 |1
grp3 |1 |0 |0
组表根据位标志(0或1)将组名称(grp1)链接到角色(报告者,供应者,管理者)
我需要一个可以返回给定用户名的角色名列表的查询。例如,给定用户' tuser'在grp1和grp2中,返回供应商和经理的角色列表
Role
provisioner
manager
我尝试了以下内容,它似乎有效,但我必须找到一种方法来简化它:
select distinct Role, 'Roles' from
(
select 'Reporter' as Role from
(
select * from Groups g where g.name in
(
select groupname from UserGroupLink l where l.username='tuser'
)
) x
where x.reporter>0
union
select 'Provisioner' as Role from
(
select * from Groups g where g.name in
(
select groupname from UserGroupLink l where l.username='tuser'
)
) x
where x.provisioner>0
union
select 'Manager' as Role from
(
select * from Groups g where g.name in
(
select groupname from UserGroupLink l where l.username='tuser'
)
) x
where x.manager>0
) z
以上查询有效,但会与用户名' tuser'进行比较。三次,每个角色一次。如果可能的话,我需要修改查询,只在一个地方使用用户名字符串文字(对于Java JAAS安全性,如果有人好奇的话)。有谁知道这是否可行?
答案 0 :(得分:1)
如果您不介意将角色放入一行,您可以执行以下操作:
select concat_ws(',',
(case when reporter > 0 then 'Reporter'
when Provisioner > 0 then 'Provisioner'
when Manager > 0 then 'Manager'
end)
) as roles
from user u join
usergrouplink ugl
on u.tuser = ugl.tuser join
groups g
on ugl.groupname = g.groupname
where u.name = 'tuser';
如果您有控制权,则应考虑通过创建groups
表来规范化GroupRoles
表,每个组一个角色,每个角色一行。
编辑:
如果您需要多行,您仍然可以这样做。把它放在一行就更容易了:
select (case when reporter > 0 and n.n = 1 then 'Reporter'
when Provisioner > 0 and n.n = 2 then 'Provisioner'
when Manager > 0 and n.n = 3 then 'Manager'
end) as role
from user u join
usergrouplink ugl
on u.tuser = ugl.tuser join
groups g
on ugl.groupname = g.groupname cross join
(select 1 as n union all select 2 union all select 3
) n
where u.name = 'tuser'
having role is not NULL;
请注意,这会使用MySQL中的having
子句扩展。您可以在没有group by
的情况下使用它,并为条件使用列别名。否则,逻辑将需要子查询或复杂的where
语句。