3

我有两个 MySql 表如下:

resource
-----------------------------------------------
id   name           group   owner_id
-----------------------------------------------
1    MyResource1    hs      11
2    MyResource2    ms      24
3    MyResource3    ps      11
...

resource_access
-----------------------------------------------
id   resource_id    user_id
-----------------------------------------------
1    1              12
2    2              24
3    2              11
4    3              15
...

现在,第一个表是资源列表,当然,owner_id列中还有它们各自的所有者。第二个表是与另一个用户“共享”该资源的结果。由于来自所有者交换的混乱清理,该表resource_access 可能包含与一行中的user_id等效的记录。owner_idresource_access

我只想获取用户有权访问的任何资源的 ID、名称和组,无论他们是所有者还是已与他们共享。这是我对示例用户 (24) 的 MySQL 查询:

SELECT resource.id, resource.name, resource.group 
FROM `resource` 
INNER JOIN resource_access ON (
    resource.owner_id='24' 
    OR (
        resource_access.user_id='24' AND 
        resource_access.resource_id=resource.id
    )
)

现在,它多次返回资源号 2 的 、 和 (如 12 次idnamegroup有没有可能的原因?我已经尝试加入LEFTRIGHT得到相同的结果。表中有很多记录resource,但没有与 2 的记录。与同一用户两次共享资源id没有重复行。resource_access

提前致谢。

4

3 回答 3

7

利用:

SELECT DISTINCT resource.id, resource.name, resource.group

删除重复项。

内部连接在概念上的工作方式是它在两个表之间产生一个完整的叉积。此叉积包含输入表中每对行的一行。然后它保留匹配所有ONWHERE条件的行,并将其作为结果集返回。如果两个表之间有多个匹配行,您将在结果集中获得多行。

如果您从两个表中选择列,您会发现它们实际上不是同一行。它们只是表中的数据相同resource,但表中的数据不同resource_access。但是您没有在结果中显示后面的那些列。使用DISTINCT合并结果中的所有这些行。

于 2014-06-29T22:45:01.190 回答
1

因为您只是从resource表中选择,我建议将条件放在where子句中,而不是使用显式join

SELECT r.id, r.name, r.group 
FROM `resource` r
WHERE r.owner_id='24' or
      EXISTS (select 1
              from resource_access ra
              where ra.resource_id = r.id and
                    ra.user_id = '24' 
             );

有了这个逻辑,“加入”就不能产生重复。

于 2014-06-29T22:48:49.153 回答
0

选择资源的所有权,然后将其联合到具有访问权限的资源。结果user_id列与您的不同WHERE RA.user_id value意味着资源是共享给他们的,而不是他们拥有资源。希望这可以帮助。

SELECT resource.name,resource.group,resource.owner_id AS user_id
  FROM resource
  WHERE resource.owner_id = '11'

UNION

SELECT R.name,R.group,R.owner_id AS user_id
  FROM resource_access RA 
  LEFT JOIN resource R 
     ON (R.id=RA.resource_id)
  WHERE RA.user_id = '11';
于 2014-06-29T23:19:26.700 回答