建立一个允许用户互相关注的社交网站,并执行一个业务规则,只有当两个用户互相关注时才允许DM。
以下内容存储在查找中:
TABLE FOLLOWS
- userA_ID FK
- userB_ID FK
给定FOLLOWS
表中的数据集:
|userA_ID |userB_ID |
-----------------------
|123 |456 | <- Gerald follows Jane
|789 |456 | <- Grace follows Jane
|456 |789 | <- Jane follows Grace
如果我以Jane的身份登录,我可以DM Grace,但不能DM Gerald,反之亦然。
我的当前查询....
-- mutual followers
SELECT DISTINCT (u.id) AS userId, u."name" AS "userName"
FROM "Follows"
INNER JOIN "User" u ON u.id = "userA_ID"
WHERE "userB_ID" = $1
INTERSECT
SELECT DISTINCT (u.id) AS "userId", u."name" AS "userName"
FROM "Follows"
INNER JOIN "User" u ON u.id = "userB_ID"
WHERE "userA_ID" = $1
...感觉很笨拙.有没有办法用一个SELECT而不是UNION来写这个?
3条答案
按热度按时间sqserrrh1#
是的,你不需要使用
UNION
INTERSECT
。交集的计算基本上是一个WHERE EXISTS(…)
语句,检查第二个查询的结果中是否有相同的值。但是通过直接使用EXISTS
可以简化得到这些结果的查询-你不需要再次连接User
:顺便说一句,你也可以删除
DISTINCT (u.id)
--如果你在User(id)
和Follows(userA_ID, userB_ID)
上的主键/唯一约束设置正确,那么这个查询就不能为同一个用户生成多行。实际上,你可以将
WHERE EXISTS(*)
表示为另一个JOIN
:另一种简化查询的方法是将交集移动到一个直接的子查询,专门用于共同的关注者:
hrysbysz2#
您需要的是一个
inner join
,而人们大多不知道的是,您并不局限于一个简单的a.id = b.a_id
答案
并得到
至于如何只做一行,我还不知道,如果你需要这个生产,你可以离开它,虽然。使它不同不会更快。
解释
我做得很快
你的主要问题
结果:
你可以稍微修理一下,不过没关系
68de4m5k3#
您的要求可以按照每个共同的追随者进行翻译,在表“追随者”中将有1个以上的相关记录。