【问题标题】:ManyToMany query question多对多查询问题
【发布时间】:2011-08-08 22:14:21
【问题描述】:

我有三个简单的表:基于多对多的组、权限和 group_permissions。 我的问题是在执行查询时,给定组 id (pk),将检索具有所有权限的结果集,包括与给定组关联的权限和与组无关的权限。

我尝试过类似的方法:

SELECT * 
FROM permission
LEFT JOIN group_permissions ON group_permissions.permission_id = permission.id  
LEFT JOIN group ON group_permissions.group_id = group.id
WHERE group.id = 123

但它只是不起作用......

有什么建议吗?

谢谢大家的回答,我在不到 30 分钟的时间内解决了我的问题!这不是什么东西吗?

SELECT * 
FROM auth_permission
LEFT JOIN auth_group_permissions ON auth_group_permissions.permission_id = auth_permission.id AND auth_group_permissions.group_id = 123    
LEFT JOIN auth_group ON auth_group.id = auth_group_permissions.group_id 

【问题讨论】:

  • 这是完整的查询吗?您提到的给定组 ID 的测试在哪里?
  • 我忘了 :( 刚刚编辑过。tk
  • 这就是我的怀疑,这就是我问这个问题的原因。正如我在下面对 Steve Mayne 的评论中提到的,您不能在 where 子句中检查该值,因为它否定了左连接。我已经发布了一个答案来解决这个问题。

标签: mysql sql django


【解决方案1】:

group 是 SQL 中的关键字。使用关键字命名表或字段通常不是一个好主意,但如果必须这样做,则必须将它们括在通常位于键盘左上角的反引号字符中,在转义键下:

SELECT * 
FROM permission
LEFT JOIN group_permissions ON group_permissions.permission_id = permission.id  
LEFT JOIN `group` ON group_permissions.group_id = `group`.id

用于指定的组 ID 是什么?如果你不使用它进行过滤,它需要指定什么?

【讨论】:

  • 但是您不想在 WHERE 子句中检查 group.id = 123,这将否定 LEFT JOIN 并强制它表现得像一个 INNER JOIN。
  • 确实如此 - 老实说有点令人困惑,因为它说“检索所有权限” - 那么指定了什么?
  • 我想检索所有权限(就像 SELECT * FROM 权限一样),但要区分给定组使用的权限和未使用的权限。
  • 刚刚在上面编辑过。抱歉 ;),仍然如上所述,它会否定 LEFT JOIN。
【解决方案2】:

正如在各种 cmets 中所提到的,您不能在 WHERE 子句中测试 group.id 的值,因为它会否定 LEFT JOIN 并强制它表现得像 INNER JOIN。

相反,将该测试作为 JOIN 条件的一部分:

SELECT * 
    FROM permission
        LEFT JOIN group_permissions 
            ON group_permissions.permission_id = permission.id  
        LEFT JOIN `group` 
            ON group_permissions.group_id = `group`.id
                AND `group`.id = 123

【讨论】:

  • 你提出了一个很好的观点,现在 LEFT JOIN 没有被否定。尽管如此,我还是得到了重复的项目(例如,与其他组关联的权限)我设法像这样绕过它:SELECT * FROM permission LEFT JOIN group_permissions ON group_permissions.permission_id = permission.id AND group_permissions.group_id = 123 LEFT JOIN group ON group_permissions.group_id = group.id 谢谢
  • 抱歉格式化了,可以看看如何把代码放在这里:)
猜你喜欢
  • 2011-07-29
  • 1970-01-01
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 2011-04-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多