简体   繁体   English

为配对中的另一个用户选择

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM