连接查询有问题

时间:2009-07-01 15:29:45

标签: sql mysql postgresql

我正在网络应用中实现家庭酿造ACL系统,这让我很难过。我相信这是微不足道的,只是无法理解它。

我有一对多关系中的3个表:
resourceperms_groupperms_users 其中perms_group是一个关键表,而perms_users允许我根据需要微调每个用户的访问权限(它加起来perms_users或只是简单地覆盖它,两个表都将权限存储为布尔值在单独的列中)。

我正在尝试从资源中获取内容以及在单个查询中获取权限:

SELECT *
FROM resource
LEFT OUTER JOIN perms_groups ON resource.id = perms_group.res_id
LEFT OUTER JOIN perms_users ON resource.id = perms_users.res_id
WHERE resource.id = 1
    AND perms_group.group_id = 2
    AND perms_users.user_id = 3

现在麻烦的是很少设置用户的精细权限,在这种情况下,上面的查询将返回0行。我要告诉的是,如果有任何设置,请为第2组和用户3 取回权限。基本上我缺少AND_IF_EXISTS运算符;)。我可以轻松地在两个查询中打破它,但因为它会在每次刷新页面时运行,所以我需要尽可能精简。目前我正在使用MySQL,但我希望稍后切换到PostgreSQL,因此理想的解决方案将是db独立的。有什么想法吗?

由于

5 个答案:

答案 0 :(得分:4)

SELECT *
FROM resource
LEFT OUTER JOIN perms_groups ON resource.id = perms_group.res_id 
                             AND perms_group.group_id = 2
LEFT OUTER JOIN perms_users ON resource.id = perms_users.res_id 
                            AND perms_users.user_id = 3
WHERE resource.id = 1

事实上,如果你在不知道自己是否有数据的情况下在桌子上写条件,那么左外连接是没用的。

答案 1 :(得分:1)

您可以尝试将WHERE子句移动到用户的联接中。群组...

SELECT *
FROM   resource
       LEFT OUTER JOIN perms_groups ON resource.id = perms_group.res_id AND perms_group.group_id = 2
       LEFT OUTER JOIN perms_users ON resource.id = perms_users.res_id AND perms_users.user_id = 3
WHERE  resource.id = 1    

答案 2 :(得分:0)

如果您将权限加入(左外连接)一行,则可以使用CASECOALESCE来实现所需内容。

答案 3 :(得分:0)

如果您的用户权限覆盖了组权限,请使用以下命令:

SELECT  permission
FROM    resource
JOIN    perms_users
ON      perms_users.res_id = resource.id
WHERE   resource.id = 1
        AND user_id = 3
UNION ALL
SELECT  permission
FROM    resource
LEFT JOIN
        perms_groups
ON      perms_group.res_id = resource.id
        AND group_id = 2
WHERE   resource.id = 1
LIMIT 1

这会更有效率,因为如果perms_groups中找到记录,此查询甚至不会查看perms_users

答案 4 :(得分:0)

为了更好地理解外连接,请阅读:

Ask the Experts: Terry Purcell on Outer Joins