[英]SELECTing for the other user of the pair
I have the following structure (simplified for brevity).我有以下结构(为简洁起见进行了简化)。 I am mostly frontend developer that suddenly needs to learn the basics of SQL, so bear with me, please :)
我主要是前端开发人员,突然需要学习 SQL 的基础知识,所以请耐心等待:)
CREATE TABLE user (
id text NOT NULL,
lastOnlineAt timestamptz NOT NULL
);
CREATE TABLE pair (
id text NOT NULL
);
CREATE TABLE userPair (
userId text NOT NULL,
pairId text NOT NULL
);
The important aspect here is that every pair
is linked to exactly 2 user
entities (through userPair
).这里的重要方面是每一
pair
都恰好链接到 2 个user
实体(通过userPair
)。 I am not sure if was the wisest approach, but I did not like the idea of having columns user1/2
inside the pair
.我不确定这是否是最明智的方法,但我不喜欢在
pair
user1/2
列的想法。
Now I need to do a SELECT that for every user
finds associated pair
s, picks the other user
of that pair
and gets his lastOnlineAt
for a comparison.现在我需要做一个选择,每
user
相关联的发现pair
S,挑选其他user
说的pair
,并得到他的lastOnlineAt
了比较。 Effectively I need to find paired users that were online in the last 5 minutes.实际上,我需要找到过去 5 分钟内在线的配对用户。
I would probably start like this.我可能会这样开始。
SELECT up.'pairId'
FROM 'userPair' AS up
LEFT JOIN pair as p
WHERE up.'userId' = $userId
AND p.id = up.'pairId'
But then I am getting lost in complexity here.但后来我在这里的复杂性中迷失了。
It's for the Postgres 12.它适用于 Postgres 12。
You have a syntax errors in that a left join
needs an on
and identifiers cannot be enclosed in single quotes since that makes them literals.您有一个语法错误,因为
left join
需要一个on
并且标识符不能用单引号括起来,因为这使它们成为文字。
You need to join userpair
twice to get what you want:你需要加入
userpair
两次才能得到你想要的:
SELECT u2.*
FROM "userPair" AS p1
JOIN "userPair" p2
ON p2."pairId" = p1."pairId"
AND p2."userId" != p1."userId"
JOIN "user" u2
ON u2.id = p2."userId"
WHERE p1."userId" = $userId
AND u2."lastOnlineAt" >= now() - interval '5 minutes'
Also, using camel case for identifier is very bad idea.此外,使用骆驼案例作为标识符是非常糟糕的主意。
One method uses a lateral join:一种方法使用横向连接:
select u.*
from userpair p cross join lateral
(values (userid, pairid), (pairid, userid)
) v(theuserid, theotherid) join
users u
on u.id = v.theotherid
where v.theuserid = ?;
This uses the lateral join to split the data into two pairs -- with the users in either order.这使用横向连接将数据分成两对——用户按任意顺序排列。 The first is matched to the input.
第一个与输入匹配。 The second is the other one that is returned.
第二个是返回的另一个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.