我有以下表格结构。这个想法是用户通过他们的类或特定用户覆盖对论坛拥有权限。 ('行动'在这两种情况下都是带有价值观的枚举'阅读''写')
user (id, class)
forum (id, name)
forum_permissions (forum_id, class_id, action)
forum_user_permissions (forum_id, user_id, action)
通过以下查询,我可以根据forum_permissions中我不希望的行获得额外的结果。我的意思是,即使class_id不匹配,forum_id = 3的forum_permissions上的每一行都会被返回。
SELECT forum.id AS forum_id, forum.name
FROM forum
JOIN forum_permissions ON forum_permissions.forum_id = forum.id
LEFT JOIN forum_user_permissions ON (
forum_user_permissions.forum_id = forum.id AND forum_user_permissions.user_id = 3 )
WHERE (( forum_permissions.class_id = 1 AND forum_permissions.action = 'read' )
OR
( forum_user_permissions.action = 'read' ))
e.g。我明白了:
FORUM_ID NAME
1 chat
2 support
3 secret
3 secret
3 secret
3 secret
但期望这样:
FORUM_ID NAME
1 chat
2 support
3 secret
的具体示例制作了一个SQL小提琴
答案 0 :(得分:0)
您的左连接正在添加这些额外的行。 mybe如果你改变了WHERE
WHERE forum_user_permissions.user_id is not null and (
(forum_permissions.class_id = 1 AND forum_permissions.action = 'read')
OR
(forum_user_permissions.action = 'read')
)
或者
SELECT
forum.id AS forum_id, forum.name
FROM
forum
JOIN
forum_permissions
ON
forum_permissions.forum_id = forum.id
LEFT JOIN
forum_user_permissions
ON (
forum_user_permissions.forum_id = forum.id
)
WHERE forum_user_permissions.user_id = 3 and (
(forum_permissions.class_id = 1 AND forum_permissions.action = 'read')
OR
(forum_user_permissions.action = 'read')
)
但这取决于你想要获得的结果
答案 1 :(得分:0)
好吧,我自己通过对两个权限表使用LEFT JOIN来解决它,而不是将逻辑放在WHERE子句中。我不太确定这是否比我的第一次尝试更好,如果有人可以解释的话,我很乐意投票。
SELECT forum.id AS forum_id, forum.name
FROM forum
LEFT JOIN forum_permissions
ON ( forum_permissions.forum_id = forum.id
AND forum_permissions.class_id = 1
AND forum_permissions.action = 'read' )
LEFT JOIN forum_user_permissions
ON ( forum_user_permissions.forum_id = forum.id
AND forum_user_permissions.user_id = 3
AND forum_user_permissions.action = 'read' )
WHERE forum_permissions.forum_id IS NOT null OR forum_user_permissions.forum_id IS NOT null
完整的数据集包含在下面,因为我猜小提琴将在某个时候到期。
INSERT INTO user
(`id`, `class`)
VALUES
(1, 1), (2, 1), (3, 1), (4, 2);
INSERT INTO forum
(`id`, `name`)
VALUES
(1, 'chat'), (2, 'support'), (3, 'secret');
INSERT INTO forum_permissions
(`forum_id`, `class_id`, `action`)
VALUES
(1, 1, 'read'), (1, 1, 'write'),
(1, 2, 'read'), (1, 2, 'write'),
(2, 1, 'read'), (2, 1, 'write'),
(2, 2, 'read'), (2, 2, 'write'),
(3, 2, 'read'), (3, 2, 'write'),
(3, 3, 'read'), (3, 3, 'write');
INSERT INTO forum_user_permissions
(`forum_id`, `user_id`, `action`)
VALUES
(3, 3, 'read'), (3, 3, 'write');