我有两个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_id
行中resource_access
的记录,因为清理混乱来自业主交易所。
我只想获取用户有权访问的任何资源的ID,名称和组,无论他们是所有者还是已与他们共享。这是我对示例用户的MySQL查询(24):
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的id
,name
和group
(如12)。有可能的原因吗?我尝试了LEFT
和RIGHT
加入,并得到了相同的结果。 resource
表中有许多记录,但没有id
为2的记录。resource_access
中没有重复的行与同一用户共享资源两次。
提前致谢。
答案 0 :(得分:6)
使用:
SELECT DISTINCT resource.id, resource.name, resource.group
删除重复项。
内连接在概念上的工作方式是它在两个表之间产生完整的交叉产品。此交叉产品为输入表中的每个对行包含一行。然后它保留与所有ON
和WHERE
条件匹配的行,并将其作为结果集返回。如果两个表之间有多个匹配的行,那么结果集中将有多行。
如果您从两个表中选择列,您会发现它们实际上并不是同一行。它们只有resource
表中的相同数据,但来自resource_access
表的数据不同。但是你没有在结果中显示后面的那些列。使用DISTINCT
合并结果中的所有这些行。
答案 1 :(得分: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'
);
有了这个逻辑,“加入”就不能产生重复。
答案 2 :(得分: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';