面对多个表连接中的问题

时间:2013-05-02 13:41:06

标签: mysql sql join

有4张桌子。

  • 项目(item_id,item_name,item_owner)
  • groups(grp_id,grp_name,grp_owner)
  • 用户(grp_id,usr_ref)
  • 分享(item_id,grp_id)

我的目标是获取所有项目的列表,其中item_owner = user_id(比如123)或user_id属于与该项目共享的组。

用于检索与特定user_id所属的组共享的所有项目的基本查询实现

select i.item_id from items i
left outer join share on share.item_id = i.item_id
left outer join users on users.grp_id = share.grp_id
left outer join groups on groups.grp_id = share.grp_id
where users.usr_ref = user_id

要包含user_id为所有者的所有其他元素,我会执行类似

的操作
select * from items where owner = user_id or item_id in ( 
select i.item_id from items i
left outer join share on share.item_id = i.item_id
left outer join users on users.grp_id = share.grp_id
left outer join groups on groups.grp_id = share.grp_id
where users.usr_ref = user_id )

我认为这是一个非常糟糕的实现,因为每次都需要在从连接获得的数组中搜索item_id。我怎样才能改进我的sql语句。

还有其他方法可以重新设计我的表结构,以便我可以用其他方式实现查询吗?

提前完成。

3 个答案:

答案 0 :(得分:2)

在这种情况下,您需要INNER JOIN,因为您需要获取所有表上具有连接的项目。您当前的查询使用LEFT JOIN,这就是为什么即使一个未与任何用户关联的项目也会显示在列表中。试一试,

SELECT  DISTINCT a.*
FROM    items a
        INNER JOIN `share` b
            ON a.item_ID = b.item_ID
        INNER JOIN groups c
            ON b.grp_ID = c.grp_ID
        INNER JOIN users d
            ON c.grp_ID = d.grp_ID
WHERE   d.usr_ref = user_ID

要进一步了解联接,请访问以下链接:

答案 1 :(得分:0)

我认为这会奏效。

select i.item_id from items i
inner join share on share.item_id = i.item_id
inner join users on users.grp_id = share.grp_id
inner join groups on groups.grp_id = share.grp_id
where (users.usr_ref = @user_id or @user_id is null) and  (i.item_id = @item_id or @item_id is null)

我猜你总是传递一个参数或另一个参数,而不是两个,所以另一个(未通过)将为空

另外,你为什么要使用左连接?使用内部代替,因为你不想要空字段

答案 2 :(得分:0)

也许我不理解你的问题,但是你不能只在你的第一个查询中使用OR

select i.item_id from items i
   left outer join share on share.item_id = i.item_id
   left outer join users on users.grp_id = share.grp_id
   left outer join groups on groups.grp_id = share.grp_id
where i.item_owner = @user_id or users.usr_ref = @user_id