sql - Postgresql 排除已经存在的友谊关系
问题描述
我有两个表:用户和友谊:
CREATE TABLE t_users (
user_id varchar PRIMARY KEY,
name varchar
);
CREATE TABLE t_friendship (
friendship_id varchar PRIMARY KEY,
from_user_id varchar,
to_user_id varchar
);
INSERT INTO t_users VALUES ('us123', 'us123');
INSERT INTO t_users VALUES ('us456', 'us456');
INSERT INTO t_users VALUES ('us789', 'us789');
INSERT INTO t_users VALUES ('us987', 'us987');
INSERT INTO t_users VALUES ('us654', 'us654');
INSERT INTO t_users VALUES ('us321', 'us321');
INSERT INTO t_friendship VALUES ('fr123', 'us123', 'us456');
INSERT INTO t_friendship VALUES ('fr456', 'us123', 'us789');
INSERT INTO t_friendship VALUES ('fr789', 'us123', 'us987');
INSERT INTO t_friendship VALUES ('fr987', 'us456', 'us123');
INSERT INTO t_friendship VALUES ('fr654', 'us456', 'us321');
INSERT INTO t_friendship VALUES ('fr321', 'us987', 'us123');
INSERT INTO t_friendship VALUES ('fr322', 'us456', 'us654');
INSERT INTO t_friendship VALUES ('fr323', 'us654', 'us123');
INSERT INTO t_friendship VALUES ('fr324', 'us789', 'us654');
INSERT INTO t_friendship VALUES ('fr325', 'us321', 'us123');
SELECT
t_users.user_id,
t_users.name
FROM t_friendship
inner join t_users on t_friendship.from_user_id = t_users.user_id
WHERE t_friendship.to_user_id = 'us123';
如何提出一个显示推荐朋友的请求,同时排除已经存在的友谊关系(from_user_id -> to_user_id)?例如'us123'、'us456'。
谢谢你。
解决方案
对于您的特定结果,您将使用:
select u.*
from t_users u
where not exists (select 1
from t_friendships f
where f.to_user_id = 'us123' and
f.from_user_id = u.user_id
) and
u.user_id <> 'us123';
SQL Fiddle 在这里。
更常见的是,友谊是对称的——这意味着如果 a/b 是朋友,那么 b/a 也是。如果此一般规则为真,您可以执行以下操作:
select u.*
from t_users u
where not exists (select 1
from t_friendships f
where f.to_user_id = 'us123' and
f.from_user_id = u.user_id
) and
u.user_id <> 'us123';
如果您想排除任一方向的朋友建议,请使用not exists
两次:
select u.*
from t_users u
where not exists (select 1
from t_friendships f
where f.to_user_id = 'us123' and
f.from_user_id = u.user_id
) and
not exists (select 1
from t_friendships f
where f.from_user_id = 'us123' and
f.to_user_id = u.user_id
) and
u.user_id <> 'us123';
此查询将不返回任何行,因为用户与所有其他用户有朋友(在某个方向)。
请注意,如果您从应用程序调用它,那么您应该使用参数而不是将用户 ID 填充到查询字符串中。
推荐阅读
- javascript - 如何在站点后将浏览器窗口大小调整为 75%
- mysql - MySQL查询列出每个用户在几个表中出现的次数
- ruby - 如何以编程方式设置 content_security_policy?
- linux - 使用 bash 将一个文件中的行内容复制到另一个文件中的特定字符位置
- javascript - 如果特定文本(价格 0)显示在 span 中,则隐藏元素
- php - 如何通过从 PostgreSQL 转换为 DQL 来完成这种动态平均?
- c# - 粒子系统没有通过代码播放
- python - Python gRPC 服务器不监听指定端口
- node.js - 安装嵌套依赖的 peerDependencies
- javascript - 尝试通过 NodeJS Lambda 将 XML 站点地图放入 AWS S3 存储桶