好吧我说有一个票证表,用户表,角色表和role_mapping表。票证由用户拥有。用户可以拥有1个或多个角色。 roles表定义角色,而role_mapping表将用户映射到他/她的角色(角色基本上是权限)。所以我想要做的是加入用户,票证和角色映射(Oracle SQL):
SELECT t.ticket_id, u.user_id, rm.role_id
FROM tickets t
JOIN users u on u.user_id = t.user_id
JOIN role_mappings rm on rm.user_id = u.user_id
WHERE ...
因此,如果给定用户具有多个角色,那么这当然会生成具有相同ticket_id的多行。我想要的是,如果role_id是'102',只生成一行值为'102',否则,只生成一行对应给定用户的最大角色值,即如果用户有role_id 101,102,105则选择102 ,但如果是101,105则选择105。
这是如何实现的?
答案 0 :(得分:1)
我认为你在你的例子中犯了一个错误(当你的101,102,105与你的书面描述不一致时选择了102) - 但你在联接和使用聚合函数后所寻找的是group by
(max
)选择你的最大价值角色。类似的东西:
SELECT t.ticket_id, u.user_id, max(rm.role_id)
FROM tickets t
JOIN users u on u.user_id = t.user_id
JOIN role_mappings rm on rm.user_id = u.user_id
WHERE ...
GROUP BY t.ticket_id, u.user_id
如果您想要一行中的所有角色,请查看GROUP_CONCAT
<强>更新强>
要满足角色102
的要求,首选方法是排除具有角色102的故障单用户的结果,然后使用union
这样的事情:
SELECT t.ticket_id, u.user_id, max(rm.role_id)
FROM tickets t
JOIN users u on u.user_id = t.user_id
JOIN role_mappings rm on rm.user_id = u.user_id
WHERE u.user_id NOT IN (
SELECT t.ticket_id, u.user_id, max(rm.role_id)
FROM tickets t
JOIN users u on u.user_id = t.user_id
JOIN role_mappings rm on rm.user_id = u.user_id
WHERE rm.role_id = 102)
GROUP BY u.id
UNION ALL
SELECT t.ticket_id, u.user_id, rm.role_id
FROM tickets t
JOIN users u on u.user_id = t.user_id
JOIN role_mappings rm on rm.user_id = u.user_id
WHERE rm.role_id=102