FROM中未使用的表崩溃查询

时间:2012-11-14 13:49:50

标签: mysql sql

我有以下数据库表:

user
    int unsigned id
    varchar      login

group
    int unsigned id
    varchar      label

right
    int unsigned id
    varchar      label

user_group
    int unsigned userId
    int unsigned groupId

user_right
    int unsigned userId
    int unsigned rightId

group_right
    int unsigned groupId
    int unsigned rightId

当使用user_right或group_right表(相应地)关联权限时,权限被视为已授予组或用户。 我有以下查询应该从他的登录中检索用户的权限:

SELECT DISTINCT `R`.`id`,
                `R`.`label`
FROM `user` `U`,
     `right` `R`,
     `user_right` `UR`,
     `user_group` `UG`,
     `group_right` `GR`
WHERE (`U`.`id` = `UR`.`userId`
       AND `R`.`id` = `UR`.`rightId`
       OR `U`.`id` = `UG`.`userId`
       AND `UG`.`groupId` = `GR`.`groupId`
       AND `R`.`id` = `GR`.`rightId`)
  AND `U`.`login` = 'admin'

当用户与权限和组关联时,查询确实有效并返回正确的权限。但是当用户没有组时,查询不起作用。如果我删除未使用的表(user_group和group_rights),它会再次起作用。

我应该在查询中添加什么来避免这种情况?我应该添加类似“OR some_column IS NULL”的内容吗?如果你能解释我为什么这样我再也不会遇到这个问题,我将不胜感激。

提前致谢。

一些示例数据:

user (id, login)
1 'admin'

right (id, label)
1 'r1',
2 'r2',
3 'r3'

user_right (id, label)
1 1

感谢阅读:)

1 个答案:

答案 0 :(得分:1)

首先,您使用的是隐式联接,而且,您编写查询的方式是INNER JOIN。您应该更改查询以使用正确的显式连接,并在其中使用LEFT JOIN。像这样:

SELECT DISTINCT `R`.`id`,
                `R`.`label`
FROM `user` `U`
LEFT JOIN `user_right` `UR`
    ON `U`.`id` = `UR`.`userId`
LEFT JOIN `right` `R`
    ON `R`.`id` = `UR`.`rightId`
LEFT JOIN `user_group` `UG`
    ON `U`.`id` = `UG`.`userId`
LEFT JOIN `group_right` `GR`
    ON `UG`.`groupId` = `GR`.`groupId` AND `R`.`id` = `GR`.`rightId`
WHERE `U`.`login` = 'admin'