2013-09-26 54 views
1

好吧产生多行的人说我有一个票表,用户表,角色表,role_mapping表。票据由用户拥有。用户可以拥有1个或多个角色。角色表定义角色,而role_mapping表将用户映射到他/她的角色(角色基本上是权限)。因此,我想要做的就是用户加入,门票和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 101102105然后选择102 ,但如果101,105然后选择105

这是如何实现的?

回答

1

我认为你在你的例子中犯了一个错误(当你有101,102,105时选择了102,105,105与你的书面描述不一致) - 但是你要加入并使用一个聚合函数group bymax)挑选您的最大价值角色。喜欢的东西:

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

UPDATE

为了满足角色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

+0

啊,我作出错误是很简单其实。我已经在那里组了,但是我在group by子句中加入了rm.role_id。删除它只会给出最大值。 现在,话虽如此,我只希望做的最大值,如果用户没有ROLE_ID 102。如果他/她确实有102,我想忽略任何更高的价值和使用。你会为此做些什么? – user2064883

+0

对于像你需要使用一个case语句逻辑:http://dev.mysql.com/doc/refman/5.0/en/case.html – Matthew

+0

或不同的子查询使用和不使用记录'roleId' 102 – Matthew