PostgreSQL四表关联查询问题:获取指定权限物品数据
问题原因分析
你的问题核心出在**INNER JOIN t_friends**这个关联操作上。INNER JOIN的特性是:只有当关联的两张表都存在匹配记录时,才会返回结果。而你的OR条件包含两种情况:物品对us456开放好友权限,或者物品是public权限。
看你的数据细节:public权限的物品共有5个(it678、it123、it456、it728、it826),其中it678的所有者是us789,但你的t_friends表只有一条记录('f123', 'us123', 'us456')——us789和us456没有好友关系。当你用INNER JOIN关联t_friends时,it678这条public物品因为找不到对应的好友匹配记录,直接被过滤掉了,最终只返回了4行。
正确的SQL写法
这里提供两种可靠的解决方案,你可以根据场景选择:
方式一:改用LEFT JOIN并调整WHERE条件
把t_friends的关联改为LEFT JOIN,确保public权限的物品即使没有对应的好友关系也能被保留,同时通过WHERE条件覆盖两种权限场景:
SELECT DISTINCT t_items.item_id, t_items.owner_id, t_items.title FROM t_access_items_users JOIN t_items ON t_access_items_users.item_id = t_items.item_id LEFT JOIN t_friends ON t_items.owner_id = t_friends.from_user_id WHERE (t_friends.to_user_id = 'us456') OR (t_access_items_users.user_id = 'public');
添加DISTINCT是为了避免部分物品同时满足两种权限时出现重复行。
方式二:用UNION合并独立查询
更直观的方式是分开查询两种权限的物品,再用UNION合并(自动去重):
-- 查询us456的好友拥有的物品(好友权限) SELECT t_items.item_id, t_items.owner_id, t_items.title FROM t_items JOIN t_friends ON t_items.owner_id = t_friends.from_user_id WHERE t_friends.to_user_id = 'us456' UNION -- 查询public权限的物品 SELECT t_items.item_id, t_items.owner_id, t_items.title FROM t_access_items_users JOIN t_items ON t_access_items_users.item_id = t_items.item_id WHERE t_access_items_users.user_id = 'public';
这种方式逻辑清晰,不容易因关联类型出错,适合复杂的权限判断场景。
结果验证
两种写法最终都会返回所有符合条件的物品:包括us456的好友(us123)拥有的3个物品,加上5个public权限物品(自动去重重复的it123),总共7条有效记录。
内容的提问来源于stack exchange,提问作者Sergey Kozlov
相关产品推荐
相关产品推荐

