2012-11-13 46 views
1

我一直在试图自己找到这个答案,但是我对此太糟糕了,所以我来这里希望你能帮助我。如何在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, 
    boolean  granted 
) 
group_right(
    int unsigned groupId, 
    int unsigned rightId, 
    boolean  granted 
) 

和3的配置参数(PHP定义):

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

  • RESULTING_RIGHTS,可以是MIN_RIGHTSMAX_RIGHTS。 它指示在确定结果权限时是否使用“AND”或“OR”运算符。例如,如果对于“r1”,组“g1”为TRUE,组“g2”和“g3”为FALSE,“MIN_RIGHTS”为FALSE,并且“MAX_RIGHTS”为TRUE。

  • RIGHTS_PRIORITY,可以是USER_OVER_GROUPGROUP_OVER_USER。 它表明用户自己的权利是否覆盖他的组权限,或者组的权限是否覆盖用户自己的权限。

我想拿出,将找到一个用户用途不同所拥有的权利,考虑到这些3个参数和他的小组单查询,但我真的没有关于如何做到这一点的想法。我也可以做多个查询并完成PHP方面的一部分工作,但是我想避免多次查询,因为我希望我的应用程序足够快以支持诸如AJAX自动完成和其他类似的东西。

我明白,如果没有人想或有时间来帮助我:p感谢阅读。

编辑: 一些样品DATAS:

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和/或登录被认为是已知的。

+0

可以请你发布一些样本数据和期望的输出? –

+0

任何特殊的原因,它必须被塞进一个单一的查询? –

+0

是的,我想要很短的执行时间。但是,如果运行2/3查询速度并不慢,那么也可以。 – Virus721

回答

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

+0

非常感谢您花时间回答我:)我会试试这个! – Virus721