如何编写带排除逻辑的SQL JOIN查询?求助多表关联SQL语句
嗨,我来帮你搞定这个SQL查询的问题!
首先咱们理清楚需求核心:当某个用户请求位置数据时,要把所有和他有黑名单关联的用户(不管是他拉黑的人,还是拉黑他的人)的位置排除掉,如果你的示例里还要求用户不能查看自己的位置,咱们也可以加上这个逻辑。
方案一:仅排除黑名单关联用户的位置(符合你问题描述的核心需求)
这个查询会返回所有和请求用户没有黑名单关系的用户的位置,包括请求用户自己的:
SELECT l.* FROM location l WHERE l.uuid NOT IN ( -- 找出当前用户拉黑的所有人 SELECT blockedid FROM blacklist WHERE blockerid = :request_user_id UNION -- 找出所有拉黑当前用户的人 SELECT blockerid FROM blacklist WHERE blockedid = :request_user_id )
方案二:排除黑名单关联用户 + 自己的位置(匹配你给出的示例结果)
如果需要像示例里那样,用户10请求时连自己的位置也看不到,只返回用户12的,那咱们在排除列表里加上请求用户自己的ID就行:
SELECT l.* FROM location l WHERE l.uuid NOT IN ( SELECT blockedid FROM blacklist WHERE blockerid = :request_user_id UNION SELECT blockerid FROM blacklist WHERE blockedid = :request_user_id UNION -- 加上这一行,排除当前用户自己的位置 SELECT :request_user_id )
逻辑说明
- 用
UNION把两种黑名单关系的用户ID合并(避免重复):一种是当前用户作为拉黑者对应的被拉黑ID,另一种是当前用户作为被拉黑者对应的拉黑ID。 NOT IN用来过滤掉这些受限用户的位置记录。- 这里的
:request_user_id是占位符,不同数据库的写法可能不一样:比如MySQL用?,PostgreSQL用$1,你可以根据自己用的数据库调整。
咱们用你的示例测试一下:
- 当请求用户是12时,黑名单关联的用户ID为空,所以返回所有3条位置记录;
- 当请求用户是10时,黑名单关联的ID是11,加上自己的ID10,所以只返回uuid=12的位置,完全符合你的示例要求。
内容的提问来源于stack exchange,提问作者Pavel Sarpov
相关产品推荐
相关产品推荐

