1

好吧,假设我有一张票表、用户表、角色表和角色映射表。票归用户所有。一个用户可以有 1 个或多个角色。角色表定义角色,而角色映射表将用户映射到他/她的角色(角色基本上是权限)。所以我想做的是加入用户、票证和角色映射(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。

这是如何实现的?

4

1 回答 1

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

在没有门票表的情况下在这里摆弄:http ://sqlfiddle.com/#!2/cc1c6/5

于 2013-09-26T21:32:50.937 回答