1

チケット テーブル、ユーザー テーブル、ロール テーブル、および 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」の行を1つだけ生成することです。それ以外の場合は、特定のユーザーが持つ最大の役割値に対応する行を1つだけ生成します。つまり、ユーザーが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

すべてのロールを 1 行にまとめたい場合は、チェックアウトしてくださいGROUP_CONCAT

アップデート

ロールを優先するという要件を満たすには、1021 つの方法として、ロール 102 のチケット ユーザーを持つ結果を除外し、次を使用して 2 番目のクエリにそれらを追加します。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 に答える