3

有4张桌子。

  • 项目(item_id、item_name、item_owner)
  • 组(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 语句。

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

提前谢谢。

4

3 回答 3

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

要进一步了解有关联接的更多信息,请访问以下链接:

于 2013-05-02T13:45:34.990 回答
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)

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

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

于 2013-05-02T13:45:37.363 回答
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
于 2013-05-02T13:48:28.770 回答