如何在SQL中编写这个?

时间:2012-11-13 13:21:06

标签: php sql associations rights

我一直试图自己找到这个答案,但我真的太糟糕了,所以我来这里希望你能帮助我。

我有以下数据库表:

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,
    boolean      granted
)
group_right(
    int unsigned groupId,
    int unsigned rightId,
    boolean      granted
)

3个配置参数(PHP定义):

  • GRANTED_BY_DEFAULT ,可以是TRUEFALSE。 它表示,如果没有为组或用户指定权利(即不在关联表中),则是否授予权利。

  • RESULTING_RIGHTS ,可以是 MIN_RIGHTS MAX_RIGHTS 。 它表示是否使用" AND"或"或"运营商在确定结果权利时。例如,如果对于" r1",则该组" g1"是真的和团体" g2"和" g3"有错误," MIN_RIGHTS"你得到FALSE,用" MAX_RIGHTS"你得到了。

  • RIGHTS_PRIORITY ,可以是 USER_OVER_GROUP GROUP_OVER_USER 。 它表示用户自己的权利是否覆盖了他/她的群组的权利,或者群组的权利是否超越了用户自己的权利。

我想提出一个单一的查询,可以找到用户有效的权利,考虑到这3个参数和他的团队,但我真的不知道如何去做。我也可以进行多个查询并在PHP方面完成部分工作,但我想避免多次查询,因为我希望我的应用程序能够快速完成AJAX自动完成和其他类似的事情。

我知道如果没有人想要或没有时间帮助我:p感谢您的阅读。

编辑: 一些样本数据:

user (id, login) :
1 "Admin"

group (id, label) :
1 "g1"
2 "g2"
3 "g3"

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

user_group (userId, groupId) :
1 1
1 2

user_right (userId, rightId) :
1 1 true
1 2 false

group_rights (groupId, rightId) :
1 1 true
1 2 false
2 1 false
2 3 true

输出将是(right_id,right_label)行的列表,具体取决于参数和其他表的行。

检索权限时,用户ID和/或登录被视为已知。

1 个答案:

答案 0 :(得分:2)

DECLARE @USERID INT = 1,
        @GRANTED_BY_DEFAULT INT = 0,
        @RESULTING_RIGHTS VARCHAR(20) = 'MIN_RIGHTS',
        @RIGHTS_PRIORITY VARCHAR(20) = 'USER_OVER_GROUP'

SELECT 
    R.ID,
    R.NAME,
    CASE
        WHEN MAX(UR.Value) IS NULL AND MAX(GR.Value) IS NULL THEN
            @GRANTED_BY_DEFAULT
        WHEN MAX(UR.Value) IS NOT NULL AND MAX(GR.Value) IS NOT NULL THEN
            CASE
                WHEN @RIGHTS_PRIORITY = 'USER_OVER_GROUP' THEN
                    MAX(UR.Value)
                ELSE
                    CASE 
                        WHEN @RESULTING_RIGHTS = 'MIN_RIGHTS' THEN
                            MIN(GR.Value)
                        ELSE
                            MAX(GR.Value)
                    END
            END
        WHEN MAX(GR.Value) IS NULL THEN
            MAX(UR.Value)
        ELSE
            CASE
                WHEN @RESULTING_RIGHTS = 'MIN_RIGHTS' THEN
                    MIN(GR.Value)
                ELSE
                    MAX(GR.Value)
            END
    END VALUE
FROM
    [Right] R
    CROSS JOIN [User] U
    LEFT JOIN [User_Right] UR
        ON R.ID = UR.RightID
        AND UR.UserID = U.ID
    LEFT JOIN [User_Group] UG
        ON UG.UserID = U.ID
    LEFT JOIN [Group_Right] GR
        ON UG.GroupID = GR.GroupID 
        AND GR.RightID = R.ID
WHERE
    U.ID = @USERID
GROUP BY 
    R.ID,
    R.NAME

这是一个SQL小提琴示例SQL Fiddle