2

我有两个表
用户列:uid、名称、邮件等
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 1 rid 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')

对于长期维护,我不想在每次添加角色时都更新代码,这将导致一个长查询。

我查看了以下内容:
Aggregating Rows
Filtering distinct rows in SQL

虽然有 Drupal 函数可以让我获得角色 id 列表,我可以在其中取消设置我不希望出现在结果数组中的角色,但我觉得我缺少对 SQL 的基本理解。有没有更好的方法在 SQL 中做到这一点?

4

3 回答 3

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 回答
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

我想要这样:

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 回答