2

列を持つ2つのテーブル
usersがあります:uid、name、mailなど
の列を持つusers_roles:uid、rid

users_roles では、ロールがユーザーに追加されるたびに、users_roles テーブルにリストされます。したがって、ユーザー 1 がロール 1 と 4 を持っているとします。

users_roles:  
uid | rid  
 1  |  1  
 1  |  4  

ロール 4 または 5 を持たないすべてのユーザーを返す必要があります。Group By と Distinct の両方を NOT IN と組み合わせて使用​​してみました。私が遭遇し続ける問題は、ユーザーがロール 1 と 4 の両方を持っている場合、それらが結果に返されることです。以下は、Group By クエリの例です。

SELECT *
FROM users AS u
LEFT JOIN users_roles AS ur ON u.uid = ur.uid
WHERE ur.rid NOT
IN ( 4, 5 )
GROUP BY ur.uid

問題は、クエリの終了後に Group By が行を結合することであると思われるため、サブクエリも試してみましたが、役に立ちませんでした。そのため、uid 1rid 4 を含むレコードを検索し、それを結果として返すだけです。

私が使用できない Drupal モジュール Views (Views Bulk Operations のセキュリティ上の問題のため) は、次の手順を実行することで目的の結果を達成します。

LEFT JOIN users_roles ON users.uid = users_roles.uid 
AND (users_roles.rid = '4' OR users_roles.rid = '5')

長期的なメンテナンスのために、ロールを追加するたびにコードを更新する必要はありません。これにより、1 つの長いクエリが作成されます。

私は以下を見ました:
Aggregating Rows
Filtering distinct rows in SQL

結果の配列に表示されたくないロールを設定解除できるロール ID のリストを取得できる Drupal 関数がありますが、SQL の基本的な理解が欠けているように感じます。SQLでこれを行うより良い方法はありますか?

4

3 に答える 3

0

私はそれが欲しいです:

SELECT *
FROM users AS u
LEFT JOIN users_roles AS ur ON (u.uid = ur.uid AND ur.rid IN ( 4, 5 ) )
WHERE ur.rid IS NULL
GROUP BY u.uid
于 2012-07-16T09:56:48.580 に答える
0

4 と 5 の両方が存在しないことを確認したい場合 (必ずしもどちらかである必要はありません)、次のように使用できます。

select  * 
from    users u 
where   not exists 
        ( 
        select  uid
        from    users_roles ur 
        where   ur.rid in (4,5)     
                and ur.uid = u.uid 
    group by uid having count(distinct rid)=2
        ) 

リストが長い場合は、可能なすべての値を含むマッピング テーブルを使用し、それを上記のクエリで使用できます。

于 2012-07-16T06:04:03.093 に答える
0

ロール 4 と 5 を持たないすべてのユーザーを返す必要があります

select  *
from    users u
where   not exists
        (
        select  *
        from    users_roles ur
        where   ur.rid in (4,5)
                and ur.uid = u.uid
        )
于 2012-07-16T05:30:10.060 に答える