独占查询,左外连接或添加查询

时间:2012-10-12 14:04:41

标签: mysql left-join tornado

我有两张桌子:

nets_permissions

    user_id INT NOT NULL,
    network_id BIGINT UNSIGNED NOT NULL,
    perm INT(3) NOT NULL,
    PRIMARY KEY(user_id, network_id)


devices_permissions

    user_id INT NOT NULL,
    network_id BIGINT UNSIGNED NOT NULL,
    device_id INT UNSIGNED NOT NULL,
    perm INT(3) NOT NULL,
    PRIMARY KEY(user_id, network_id, device_id),

nets_permissions table拥有每个用户的权限。用户可以具有不同的perm值:1表示读取权限,2表示写入权限,4表示读取+命令权限。净管理员的烫发值为3。

第二个表也是如此,但这次是针对特定网络中的设备。当网络和设备的管理员授予他们权限时,用户将被添加到此表中。但网络管理员未在此表中注册。他只在nets_permission表中,perm = 3。

我必须创建一个查询,在Tornado Web Server的处理程序中选择当前用户的权限。代码采用以下形式:

# Retrieve the current user 
    usr = self.get_current_user()
    usr_id = usr['id']
    self.lock_tables("read", ['nets_permissions as n, devices_permissions as d'])
    usrperm = self.db.query("SELECT * FROM nets_permissions as n 
         LEFT OUTER JOIN devices_permissions as d 
              ON n.network_id = d.network_id WHERE d.user_id=%s 
                 AND d.device_id=%s", 
         int(usr_id), sens.id);
    self.unlock_tables()

在usr_id中,我检索的是当前用户的id。

当前用户可以是网络的管理员(因此他只在表格nets_permissions中,perm = 3)或者在特定设备上具有某些权限的用户(因此他只在具有某些值的devices_permissions表中)烫发)。

在查询结果'userperm'中,我将使用一个整数在html页面中与权限值进行比较,并向用户显示或不显示内容。

对不起我的英语,但很难解释我的问题。我不知道我可以构造查询以获得我想要的结果。

非常感谢你的帮助。

2 个答案:

答案 0 :(得分:1)

由于用户可以在一个或两个表中,因此您可能希望使用UNION而不是Join。

Union声明的作用如下:

select * from (
   Select User_ID, network_id, network_id, perm from nets_permissions
   union
   Select User_ID, network_id, device_id, perm from devices_permissions)
where user_id = 'id'

以上格式为您提供了更大的灵活性。您可以进一步修改外部选择,使每个用户只有一行,或每个用户的最高权限,或每个用户的总权限等。

答案 1 :(得分:1)

SELECT distinct 'net', network_id, perm
FROM nets_permissions n
JOIN devices_permissions d
USING (user_id, network_id)
WHERE n.user_id = '%s'
AND d.device_id = '%s'

UNION ALL

SELECT 'device', network_id, perm
FROM devices_permissions
WHERE user_id = '%s'
AND device_id = '%s'

但是,您的数据模型似乎存在问题。如果设备没有具有该设备权限的用户,则devices_permissions中不会有一行,因此我们将无法找到其network_id。您需要更好地规范化这个:应该有一个device_network表来关联它们。